views:

416

answers:

3

I'm working on a legacy database that is complete non-sense. I have a table called movie that contains columns with names like c00, c01, c02 and so on. The table also uses non-standard primary_keys. So I've created a class called movie like this:

class Movie < ActiveRecord::Base
  set_table_name "movie"
  set_primary_key "idMovie"

  belongs_to :media_file, :foreign_key => "idFile" 

  def title
    self.c00
  end

  def plot
    self.c01
  end
end

I'd like to be able to do something like Movie.find_by_title("Die Hard") and have it return the right result. Also I'd like to be able to say Movie.create(:title => "Die Hard"). How do I do this?

A: 

I think you want alias_attribute. Check out Brian Hogan's excellent presentation from RailsConf this year.

Sarah Mei
Excellent! This removes the need for the methods defining the accessors and mutators but it doesn't let me search by the alias. So Movie.find_by_title("Die Hard") still doesn't work.
nixterrimus
A: 

The find_by_* methods use reflection, so it just isn't going to happen with Rails out-of-the-box. You can, of course, define your own methods:

def self.find_by_title(title)
    first(:conditions => { :c00 => title })
end

The next step would be to iterate over a hash of column_aliases => real_columns to use as fodder for calls to alias_attribute and define_method.

Benjamin Curtis
A: 

You really just need a combination of Sarah's answer and Ben's answer:

class Movie < ActiveRecord::Base

  # gives you Movie.find_by_title
  # and lets you chain with other named scopes
  named_scope :find_by_title, lambda { |title| { :conditions => { :c00 => title } } }

  # gives you
  #   movie.title
  #   movie.title=(title)
  # and
  #   Movie.new(:title => title)
  alias_attribute :title, :c00

end
James A. Rosen
Thank you, this is perfect!
nixterrimus