Activity
For the actual migration, the only thing you'll really need to make sure you do is copy over your database. You can download it from Heroku and then upload it to your Digital Ocean server. You can google instructions on how to move a database to another server. It's not too bad, but you'll want to be careful that when you do this, your users aren't still using the old site where you would lose some data moving servers. You'll need to disable the current app on Heroku so that you don't lose data in the migration and then change your DNS to point to the new server on Digital Ocean.
Hey Francisco,
The main difference is that on Heroku, you don't have to manage your server, update versions, patch security things, etc. It's a lot of work to run your own server but if you're willing to learn and do that, it can save you money, but it definitely won't save you time. :)
Heroku really saves a ton of time because there are so many little security patches to update constantly on your nginx, passenger, postgres, rails, ruby, redis, etc installs. That can be a fair amount of work not to mention if you want to setup backups or any of those things. You can check out the guides section in the navbar if you want to see some of my tutorials on how to do all this yourself.
The nice part is you can run all this stuff on a $10 or $20/mo server on Digital Ocean, whereas Heroku can get up to $100+/mo pretty fast. I will say, you'll probably still save time using Heroku, and if you're building something that makes money, then Heroku is probably going to be worth it. For side projects, or ones that you want to learn all the ropes of managing a server, then Digital Ocean is pretty great.
Whoops! Always something. I'll make sure this gets fixed shortly. :D
Posted in Dynamic Pricing based on user country
Hey Enrique,
You could definitely geocode their IP in order to get their country. That would probably be the most accurate version of this. Alternatively you could ask the user to fill out their country as part of the sign up process or something in order to record that without doing geocoding. The geocoding approach will look a lot more seamless on the UI side of things though, so I'd probably recommend that route.
Another option I just thought of could be taking the locale from the browser and using that to determine the country: http://stackoverflow.com/questions/7113736/detect-browser-language-in-rails I'm not sure how well this would work as the geocoded IPs would definitely be more accurate.
Nope, just overlooked that! :)
No actually. Since you've got Bundler, Capistrano will run "bundle install" on deploy and will install Rails for you. That's the nice part about it, since you have Rails inside your Gemfile, Capistrano will automatically install it!
No real advantage other than meta tags are a bit nicer to organize your HTML with. You can absolutely put that on your body tag just the same.
Just did an episode on this! https://gorails.com/episodes/advanced-caching-user-permissions-and-authorization?autoplay=1
Cache keys are definitely tough because you have to make sure that no matter what when something changes, you get that a new cache key. Setting up extra "touch" methods so that you make sure all the parents and related models get updated_at changes is pretty important, but it always ends up coming down to the individual app you're building on some level.
Posted in Opinion: Destroy or not destroy
Honestly, I would probably only purge their data on request. Depending on the app, if they cancel their account, you might give them the option to purge or keep their data, but it's another thing for them to have to worry about when they cancel. It might be nice to automatically save it and then only purge if they ask you via support. Really depends on if your users would be unhappy about that approach or not I guess.
Posted in Opinion: Destroy or not destroy
I think that's a great idea. Having both is a really great way for keeping track of history even if the record was deleted. It's a good safety measure and a lot of businesses need that.
There probably isn't going to be significant amounts of storage used unless you're talking millions of records. At that point, you're well into the multiple gigabytes of storage, but that's relatively easy to handle these days.
I haven't added both into an app for a while, but I don't think there are any gotchas that I can remember. Paranoia is going to simply flag the main record as deleted which should do what you need.
Posted in Exporting Records To CSV Discussion
Since it's a class method, you can add .to_csv on any call. Service.all.to_csv or Service.where(name: "whatever").to_csv. Both will work and will return CSV's that are only of the appropriate results.
Posted in Exporting Records To CSV Discussion
Ah, sorry I misunderstood. :)
So you have a dashboard with say like 4 tables of data and you want the user to be able to download each one independently? In that case, I would probably create a handful of extra routes and actions in that controller that just run those individual queries and export to CSV. That way you can keep them organized together nicely and still allow their separation.
The main recommendation is to try to write every cache with good defaults that's generic to the current user. For example, you'd write the cache and always include the edit link, but make it hidden by default. Then you can add some JS to display that link when the user has permissions. Obviously you'll need to write something to let the JS know what permissions the user has, so it changes things a bit.
The primary reason for having generic caches is that you end up not storing N number of copies of the cache because you have N number of users on your site. It's not good to have 1 million copies of a cache because you have 1 million users (of course). :)
DHH also talked about a similar situation in another blog or video where he mentioned handling the "share" form for Basecamp. Basically it's a list of all the users an object is shared with. They actually cache the form that includes yourself in it and then use JS to hide your name from the list because it would be weird to share something with yourself. Having a single cache really improves this and a small sprinkling of JS on top cleans it up nicely.
I'll have to do the next episode on this!
Posted in Dynamic select boxes with Rails 4
Hey John,
Any Javascript code you write inside the app/assets/javascripts folder gets included globally and is generally where you want to keep your code. It doesn't matter if you're using a regular form or a nested one, the JS won't care which is good for situations like this.
You might want to double check that you've got the right IDs for your fields because their names can change when you do nested forms. That is likely the reason that you're not getting any data filtered. Inspect the HTML on the page and make sure those form field ID's match up to your JS. With any luck, that hopefully fixes it!
That means a lot! Thanks so much for saying that Gilbert! :D
Posted in Exporting Records To CSV Discussion
This one's a little tougher, but the basic idea is this: 1. Export your CSVs to temporary files 2. Zip them up 3. Send the zip file over as the download.
You'll have to do this because there can only be one file downloaded per requests, so hence the need for creating a zip file.
You guys can remove that passenger repository and install the version directly from Ubuntu. Should be good enough for now, and then once Phusion updates their repo, you can switch back to it so you can continue to get updates. http://packages.ubuntu.com/...§ion=all
What were the issues you ran into? The key names should be scoped accordingly, but other than that, you shouldn't have any issues sharing it.
Yeah, you could probably do that too with the cache key. There are a lot of different ways to set it up, your goal is really just to make sure that the key gets updated when your database changes and that it only updates when needed. Sometimes that will depend on your app and certain cache keys will make more sense than others.
I'm hopping into the forum this morning to answer a bunch!