Posts tagged rails

All posts

Simple good practices you're probably not following

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.


Broken AJAX requests after updating to Rails 2.3.15

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.

  1. Add the csrf_meta_tag line in the header section of your application layout.
  2. 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.


Update your Rails NOW *Updated*

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!

Insight on the bug causing this ‘emergency’: http://www.insinuator.net/2013/01/rails-yaml/

Things to have into account when updating:

Rails 3.0.x apps over Ruby 1.8.x:

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.


Local static assets serving over server in production mode.

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:

  config.serve_static_assets = false

From false to true.

And that’s it.


Introducing Capistrano

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 :log do
    desc "Tail production log file"
    task :tail, :roles => :app do
      run "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'; exit 0; }
        # this is to have a cleaner output

        puts "#{channel[:domain]}: #{data}"
        break if stream == :err
      end
    end
  end

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 :tidydumps do
    puts '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"
  end

  desc "Downloads the las db dump"
  task :getlastdump do
    puts "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}/"
  end

  desc "Creates a dump and downloads it"
  task :getnewdump do
    db.backup
    db.getlastdump
  end

  desc "Downloads ALL THE DUMPS!!"
  task :getalldumps do
    puts "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.