rails dynamic attributes
I'd like to have a number of dynamic attributes for a User model, e.g., phone, address, zipcode, etc., but I would not like to add each to the database. Therefore I created a separate table called UserDetails
for key-value pairs and a belongs_to :User
.
Is there a way to somehow do something dynamic like this user.phone = "888 888 8888"
which would essentially call a function that does:
UserDetail.create(:user => user, :key => "phone", :val => "888 888 8888")
and then have a matchin开发者_Python百科g getter:
def phone
UserDetail.find_by_user_id_and_key(user,key).val
end
All of this but for a number of attributes provided like phone, zip, address, etc., without arbitrarily adding a ton of of getters and setters?
You want to use the delegate command:
class User < ActiveRecord:Base
has_one :user_detail
delegate :phone, :other, :to => :user_detail
end
Then you can freely do user.phone = '888 888 888'
or consult it like user.phone
. Rails will automatically generate all the getters, setters and dynamic methods for you
You could use some meta-programming to set the properties on the model, something like the following: (this code was not tested)
class User < ActiveRecord:Base
define_property "phone"
define_property "other"
#etc, you get the idea
def self.define_property(name)
define_method(name.to_sym) do
UserDetail.find_by_user_id_and_key(id,name).val
end
define_method("#{name}=".to_sym) do |value|
existing_property = UserDetail.find_by_user_id_and_key(id,name)
if(existing_property)
existing_property.val = value
existing_property.save
else
new_prop = UserDetail.new
new_prop.user_id = id
new_prop.key = name
new_prop.val = value
new_prop.save
end
end
end
精彩评论