I have a legacy database which I\'m trying to model using Rails. One of the tables has a column named attributes
, which is a name reserved by Rails I think.
class << self
def instance_method_already_implemented?(method_name)
return true if method_name =~ /^attributes/
super
end
end
This patch is fine and was working for me mostly, but when you check something like Album.column_names and Album.columns.collect(&:name) you would still get all columns. Also this would fail.
a = Album.last
a = Album.new(a.attributes)
To have rails fully ignore a column you could do this.
class Album < ActiveRecord::Base
set_table_name "album"
## --------------------- Ignore columns patch ------
@@ignore_column_pattern = /^column_one|^column_two/
class << self
alias :all_columns :columns
def columns
@columns_filt ||= all_columns.reject { |col| col.name =~ @@ignore_column_pattern }
end
end
alias :all_attribute_names :attribute_names
def attribute_names
@attr_names_filt ||= all_attribute_names.reject { |att| att =~ @@ignore_column_pattern }
end
## ------------------- / Ignore columns patch ------
belongs_to :artist
has_many :tracks, :through => :album_tracks
end
Also I used an array to store the columns I didn't want but you could still use the regex way too! Now the only way that you can find out about the column is using connection ie.
Album.connection.columns("albums").collect(&:name)
(This is an old question but still figures in Google so I'll add a belated answer)
I've found the best way to restrict data loaded by an ActiveRecord model is to create a database view that only contains the columns you wish to load. You can point your ActiveRecord model at the constrained view using ActiveRecord's table_name method. Native SQL tools can still manipulate the underlying table, but ActiveRecord will only see (and consequently load) the columns explicitly included in the view.
Solved this using a combination of stuff from Robin's link and some other SO answers
class Album < ActiveRecord::Base
set_table_name "album"
class << self
def instance_method_already_implemented?(method_name)
return true if method_name =~ /^attributes/
super
end
end
belongs_to :artist
has_many :tracks, :through => :album_tracks
end
Did the trick. I used a big sweeping change to return true without throwing an error for all methods starting with attributes
, and I don't think its caused any problems elsewhere.