Silence is Foo Mental notes on Ruby, Git, Rails and whatever geeky thing

30Aug/10Off

Mimicking Rails 3’s ActiveRecord query interface in Rails 2.x

NOTICE: This is only for educational and fun purposes, nothing else. I'm not trying to say that you'll get all the pros of the new query interface in Rails 2.x, it isn't even close.

The first time I used the new ActiveRecord query interface (Rails 3) I started to get boring with the one in Rails 2.x, I can't do anything, I have to use the old query interface since converting my projects from Rails 2 to Rails 3 is not an option, so I thought to make a sort of placebo, just for fun, just to be used in my local console, and here is.

module FakeActiveRecord3Methods
  def self.included(base)
    base.class_eval do
      %w/select group order limit offset joins having/.each do |method|
        named_scope method.to_sym, lambda { |arg| { method.to_sym => arg } }
      end

      named_scope :where, lambda { |arg| { :conditions => arg } }
      named_scope :includes, lambda { |arg| { :include => arg } }
    end
  end
end

Click here to see a Gist in GitHub

I used named scopes because they are chainable, if I would have added instance methods to ActiveRecord::Base it would haven't worked as I want to, maybe there's a way to make it work that way, but this was a 5-minutes module, I didn't want to spent too much time on it.

well, I have to say I don't use this module in production servers, only locally in development mode. This is how I configure my development environment to use it:

In my environment/development.rb

config.after_initialize do
  [User, And, All, The, Models, You, Want].each do |model|
    model.class_eval do
      include FakeActiveRecord3Methods
    end
  end
end

Click here to see a Gist in GitHub

I add the models I use the most, if I need to use the FakeActiveRecord3Methods module in other model I include it in the console. To make this even easier I added to my ~/.irbrc the following code:

class Class
    public :include
end

It allows us to include a module this way:

Profile.include FakeActiveRecord3Methods

otherwise Ruby will throw an exception saying we're trying to access a private method.

It might seem cumbersome to make all of this but it isn't that hard.

It's a shame I won't be able to prove that FakeActiveRecord3Methods works in most of the cases but you can test with the examples shown in Rails Guides: Active Record Querying.

Here are some queries using this module anyways. I think all of them are self-explanatory.

User.select("id, email").limit(2)
=> [#<User id: 1, email: "e@mail.com">, #<User id: 2, email: "bar@foo.com">]
User.select("id, email").where(["created_at > ?", 1.month.ago]).order("email DESC").limit(1)
=> [#<User id: 5, email: "foo@bar.com">
User.limit(5)

User.select(:id)

User.select(:id).limit(10).offset(100)

User.order :created_at

Joins

users = User.select("users.id, profiles.company").joins(:profile)
users.first.company # => Foo Company

users.first.profile.company # => Foo Company

Includes

users = User.limit(10)
users.first.name # => Foo
users.first.profile.company # => it will query the database

users = User.includes(:profile).limit(10) # it will bring the profile as well
users.first.profile.company # it won't query the database

Of course, you should be aware that in named scopes the order really matters, be careful and remember, in Rails 3, the where, select, group, order, limit, offset, joins and includes returns an instance of ActiveRecord::Relation which is not the case in the FakeActiveRecord3Methods module, it returns an instance of ActiveRecord::NamedScope::Scope and that's because named scopes returns an instance of such class.

By the way, if you want to read the Rails 2's ActiveRecord Query Interface, you can do so clicking here

Thanks for reading.

Filed under: rails Leave a comment
19Jul/10Off

Dumping and restoring data with the YamlDB gem in Rails

What is YamlDB (yaml_db)?

YamlDb is a Rails plugin and a gem for dumping and restoring data in YAML format. It complements the database-independent schema format found in db/schema.rb. The data is saved into db/data.yml.

Some Real-world usages

  • Backup data in YAML format (database-independent)
  • Restore YAML data to virtually any database
  • Switching from say SQLite to mySQL, or other databases
  • Replicate production database data to development database with ease

You can find out how to do all of this in the following blogs:

http://www.railslodge.com/plugins/830-yaml-db
http://accidentaltechnologist.com/ruby/change-databases-in-rails-with-yamldb/
http://blog.heroku.com/archives/2007/11/23/yamldb_for_databaseindependent_data_dumps/

This plugin/gem is really good, the only thing I think it's lacking of is a command-line utility. Why? Because some times you only need to switch the database engine or replicate data one time, why would we have to install a plugin to a specific Rails application if we can have a command-line that works for all the Rails application we work in?

One of the main issues is that yaml_db works with rake tasks so although it's a gem you have to install the rake tasks in your Rails application manually.

That was the main reason I forked the yaml_db project and added it a command-line utility, the only think you'd need to do is to install my fork of the yaml_db gem, not the official one.

For instructions to install my fork click here.

Once installed just issue:

$ yaml_db -h

to see the help.

Usage:
yaml_db task environment
-  task must be an existing rake task in the yaml_db plugin.

Dumping and restoring data with the command-line utility

yaml_db won't work if you're outside a Rails app folder, so...

$ cd ~/projects/my_dummy_rails_application
Replicate production database data to the development one
$ yaml_db data:dump production
$ yaml_db data:load development
Dumping production schema to db/schema.rb and data to db/data.yml
$ yaml_db dump production

Loading db/schema.rb and db/data.yml to development database

$ yaml_db load #environment defaults to development
Filed under: rails, ruby 2 Comments