This one is simple, you might as well tattoo it all over your face, because it’s very likely you’re not doing it:
Keep your seeds.rb information up-to-date with your data model, for Pete's sake.
Make the next guy to work in that project’s life easier by not having him editing the seeds.rb file as he spends like two hours invoking rake tasks to setup database and getting fugly errors in the terminal one after another.
Be the good guy. You don’t know when you’re getting to continue other’s work in a project, and you that b-word they say about karma.
After updating Rails to 2.3.15 in a Rails 2.3 app, I found that some AJAX requests were suddenly not only not working properly, but they also were a bit tricky to debug, as they error caused the logged user to be kicked out the app.
The strangest thing was the server log claiming that my current_user was not present after the AJAX call. I needed the current_user to get to get to do the request, so it WAS there in the beginning, but in the response, the current_user ceased to exist, so… what was happening?
Well, it turned out to be that Devise (a way old version of the gem, by the way) was kicking the user out due to the impossibility of checking the CSRF token properly, because it was not being encoded and sent in the AJAX request in the first place.
Solving this is easy, and it is something that should have been done from the start. Working with ‘inherited’ legacy apps sometimes brings this sort of problems in the long run.
Add the csrf_meta_tag line in the header section of your application layout.
Modify your javascript AJAX requests so they send the AUTH_TOKEN encoded along with the rest of the data.
Here are some StackOverflow questions that helped me figure out what was happening and how to solve it: one, two, and three.
It seems that all Rails branches (2.3, 3.0, 3.1 and 3.2) have been updated to fix two severe security issues (first and second). Please refer to the Rails Weblog post for more information and take action ASAP to keep your rails apps secure!
Of course, always do this in your dev environment prior to updating your servers to make sure you’re not breaking anything.
Update rubygems to 1.8 (if needed) using gem update --system
Modify your Gemfile to specify the rails 3.0.19 version. Note: you might have to delete your local Gemfile.lock before to update it.
Run bundle.
You may need to update or specify the versions of some gems. For example I found that I had the ``factory_girl_rails`` gem on my Gemfile, but its current version doesn't work with Ruby 1.8 anymore, so I had to specify the 1.7.0 version for this gem in order to keep everything working.
You might want to use the gem clean command in order to remove the old rails (and other gems) versions once you've ensured that the app works after doing the previous steps. Beware, this might will break dependencies, run bundler afterwards to attempt to fix broken dependencies. Take extra care with your passenger gem, as you won't come across any problem with it until your actually working on your servers.
Rails 2.x apps:
If you don’t have bundler, install rails gem version 2.3.15, and after that, update your app/config/environment.rb file to use rails 2.3.15.
With this version of Rails I’ve come across this warning message when running Webrick or the Rails Console:
NOTE: Gem.source_index is deprecated, use Specification.
It will be removed on or after 2011-11-01.Gem.source_index called from
/Users/meh/.rvm/gems/ruby-1.8.7-p370@project/gems/rails-2.3.15/lib/rails/gem_dependency.rb:78.
It seems that you may solve this by updating your bundler gem (gem update bundler) to the latest version but I found that I had to downgrade the rubygems version in that gemset to version 1.6.2 (gem update --system 1.6.2) to get rid of the message.
When debugging and testing Rails 3 apps locally, you might eventually need to boot Webrick (or whatever server you use) in “production mode”
rails server -u -e production
Then when you get to -usually- localhost:3000, you might find that no images, stylesheets or javascripts are being served, and you’re getting lots of routing errors on the server output.
Don’t panic! This happens because Rails in production mode assumes that your web server (Apache, nginx, etc) will manage serving the assets.
This can be fixed by changing the 32nd line in your config/environments/production.rb file:
At my job, we decided that twice a month, a member of the team should host a talk in which he would speak about something he could teach to the others. When we spoke about this, I had just succesfully deployed my first Rails application and I kinda liked it (bear with me, I was a C++ systems dev kid for 2+ years, it was a brave new world for me), so I suggested the possibility of giving a talk on Capistrano, the Rails default-ish option for deploying automation.
I prepared a neat presentation available here (Spanish only). Its most important part is based in a live demo, so I’m sorry if you find that it doesn’t cover essential aspects like tasks syntax and such, because they were covered in the hands-on. In exchange, I offer you some simple recipes I made as examples, or by demand of a fellow dev at Wombytes. They aren’t intended as showcase of my prowess at reciping, but only as simple examples of what namespaces and tasks are about. In fact, they’re the composition of fragments and ideas picked from all around the internets.
This one allows you to see the production log as it grows, without the fuss of having to open a new terminal get into the machine via ssh and navigate to the log folder. Just an elegant cap production log:tail and there you go! In this github repo there’s a similar one, that executes tail on every log present (pre, production, whatever) instead of just one. The addition of the INT signal treatment was shamelessly taken from this post from the almighty Stackoverflow.
namespace:logdodesc"Tail production log file"task:tail,:roles=>:appdorun"tail -f #{shared_path}/log/production.log"do|channel,stream,data|# this catches the INT signal and avoids the ugly capistrano error on CTRL+C
trap("INT"){puts'Interupted';exit0;}# this is to have a cleaner output
puts"#{channel[:domain]}: #{data}"breakifstream==:errendendend
The next set of recipes make use of your regular recipe to make dumps (namely ‘backup’) of the production database, and need a couple of extra things. Basically what they do is put some order in your dumps folder, and download new dumps you create easily via scp. I don’t like the fact that they have too much folder information hardcoded on them, but it’s just a matter of refinement and good variable usage.
#put this with your variable declarations
#the LOCAL folder where you want to store database dumps
set:projects_folder,'projects'#put this with the rest of your hooks
before"db:getnewdump","db:tidydumps"# THESE TASKS GO INTO YOUR namespace :db
desc"Moves old backups to old folder"task:tidydumpsdoputs'Moving old backups to the old folder'run"mkdir -p #{shared_path}/db/backups/old"run"mv #{shared_path}/db/backups/*.gzip #{shared_path}/db/backups/old"enddesc"Downloads the las db dump"task:getlastdumpdoputs"Downloading latest dump to $HOME/#{projects_folder}/database_dumps/#{application}/"system"mkdir -p $HOME/#{projects_folder}/database_dumps/#{application}/"system"scp -P #{port}#{user}@#{domain}:/#{shared_path}/db/backups/*.gzip
$HOME/#{projects_folder}/database_dumps/#{application}/"enddesc"Creates a dump and downloads it"task:getnewdumpdodb.backupdb.getlastdumpenddesc"Downloads ALL THE DUMPS!!"task:getalldumpsdoputs"Downloading dumps to $HOME/#{projects_folder}/database_dumps/#{application}/"system"mkdir -p $HOME/#{projects_folder}/database_dumps/#{application}/"system"scp -r -P #{port}#{user}@#{domain}:/#{shared_path}/db/backups/*
$HOME/#{projects_folder}/database_dumps/#{application}/"end
Anyway, the talk went well, as only the devs were present[1] and I felt more comfortable. Some team members learnt something they didn’t know about Capistrano (yay for me!), and some others with more experience explained some things I didn’t have understood too well to me (yay for me again!). There’s a chance that I will be giving this talk sometime again in the future, so those lucky enought to see me then will get a much better and expanded experience.
This talk gave me the chance to have a conversation with Juanje Ojeda, who kindly pointed me in the direction of some nifty Chef (which is mentioned at the end of the presentation) resources, so I can delve deeper into the devops lore. I guess you’ll be reading about my findings here in the short future. Thanks, mate :)
That’s the best of it: get the satisfaction of teaching a little bit and learn a lot in the process.
[1] Having talks on thursdays at 18:30 in a god forsaken place faraway from downtown doesn’t precisely attract many peeps, no matter how interesting the talk seems to be.