2010-07-26 117 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