2011-09-30 28 views
2

使用Rails 3和ActiveModel,我無法使用self。語法來獲取基於ActiveModel對象內的屬性的值。ActiveModel字段沒有映射到訪問者

在以下代碼中,在save方法中,self.first_name計算爲nil,其中@attributes [:first_name]的計算結果爲'Firstname'(初始化對象時從控制器傳入的值)。

在ActiveRecord這似乎工作,但在ActiveModel中構建相同的類時,它不。你如何引用基於ActiveModel的類中使用訪問器的字段?

class Card 
    include ActiveModel::Validations 
    extend ActiveModel::Naming 
    include ActiveModel::Conversion 
    include ActiveModel::Serialization 
    include ActiveModel::Serializers::Xml 

    validates_presence_of :first_name 

    def initialize(attributes = {}) 
    @attributes = attributes 
    end 

    #DWT TODO we need to make sure that the attributes initialize the accessors properyl, and in the same way they would if this was ActiveRecord 
    attr_accessor :attributes, :first_name 

    def read_attribute_for_validation(key) 
    @attributes[key] 
    end 

    #save to the web service 
    def save 
    Rails.logger.info "self vs attribute:\n\t#{self.first_name}\t#{@attributes["first_name"]}" 
    end 

    ... 

end 

回答

3

我想通了。我提到的作爲對瑪麗安答案的評論的「黑客」事實上證明了如何生成ActiveRecord類的訪問器。下面是我所做的:

class MyModel 
    include ActiveModel::AttributeMethods 

    attribute_method_suffix "=" # attr_writers 
    attribute_method_suffix "" # attr_readers 

    define_attribute_methods [:foo, :bar] 

    # ActiveModel expects attributes to be stored in @attributes as a hash 
    attr_reader :attributes 

    private 

    # simulate attribute writers from method_missing 
    def attribute=(attr, value) 
    @attributes[attr] = value 
    end 

    # simulate attribute readers from method_missing 
    def attribute(attr) 
    @attributes[attr] 
    end 
end 

你可以看到同樣的事情,如果你的ActiveRecord的源代碼(lib/active_record/attribute_methods/{read,write}.rb)看看。

0

你需要ActiveModel::AttributeMethods

+0

添加以下,但self.first_name依然沒有評估:'#加載ActiveModel包括:: AttributeMethods \t# \t#define_attribute_methods [ 'FIRST_NAME'] \t#' – drsquidop

+0

同樣的問題把我帶到這個頁面。我在我的模型中包含了'ActiveModel :: AttributeMethods',並且沒有運氣調用'define_attribute_methods'。我能夠使用方法後綴對它進行黑客攻擊,但我希望ActiveModel能夠支持更簡潔的解決方案。 – David