2010-07-26 118 views
2

我有模型Person的属性名称Ruby on Rails:从虚拟属性构成模型的属性

我想使用的HTML形式的字段:FIRST_NAME

<%= f.text_field first_name%> 
<%= f.text_field surname%> 

而且我要撰写这些虚拟属性模型属性

什么是做到这一点的最好方法是什么?

我试图用composed_of,但失败了......

class Person < ActiveRecord::Base 
    composed_of :name, :class_name => 'Name', :mapping => %w(name output_name) 
end 

class Name 
    attr_reader :output_name 
    def initialize(first_name, surname) 
    @output_name = first_name + surname 
    end 
end 

@person.attributes= {"name(1s)" => 'Alex', "name(2s)" => 'Bolduin' } 
@person.name.should == 'Alex Bolduin' 

expected: "Alex Bolduin", 
got: #<Name:0x000000049d4c08 @output_name="Alex Bolduin"> (using ==) 

我用Ruby on Rails的3,但我认为解决方案是为Rails 3相似和Rails 2.3

回答

7

您应该能够做一个假装列做这样的事情在模型:

class Person < ActiveRecord::Base 
    def name 
     "#{self.first_name} #{self.surname}" 
    end 

    def name=(fullname) 
     first,last = fullname.split(' ') # or some smarter way to split 
     self.first_name = first 
     self.surname = last 
    end 
end 

应该是访问的方式与任何其他列一样,当您尝试设置name它只会调用first_namesurname的setter方法。


如果你想反其道而行之,你仍然可以使用同样的伎俩:

class Person < ActiveRecord::Base 
    def first_name 
     name.split(' ')[0] 
    end 

    def surname 
     name.split(' ')[1] 
    end 

    def first_name=(first) 
     name = [first, name.split(' ')[1]].join(' ') 
    end 

    def surname=(sname) 
     name = [name.split(' ')[0], sname].join(' ') 
    end 

end 

唯一可能不好这是一个字符串操作对于每个读取每个发生一次,两次写。您可以通过添加像这样创建之前@person.save /更新或者捕捉到控制器的事情:

@person.name = [first_name, surname].join(' ') 
+0

我想要做相反的事,我想FIRST_NAME =和姓=使复合名称 – petRUShka 2010-07-29 10:55:30

+1

所以复合名是存储在数据库中的吗? – Karl 2010-07-29 18:47:24

+0

是的,只有名字。 – petRUShka 2010-08-08 19:15:28