在activerecord模型中重新定义* _before_type_cast有什么影响

时间:2013-12-05 20:09:40

标签: ruby-on-rails ruby forms

假设我想重新定义模型中的方法:

class Model < ActiveRecord::Base
  attr_accesor :model_attr

  def model_attr
    'redefined'
  end
end

当我直接访问它时,它按预期工作,但是当我从视图中调用它时:

f.text_field :model_attr

没有。但这仍然有效:

f.text_field :model_attr, value: @model.model_attr

所以我不得不深入研究Rails代码:

def text_field(object_name, method, options = {})
  Tags::TextField.new(object_name, method, self, options).render
end

class TextField < Base # :nodoc:
  def render
    options = @options.stringify_keys
    options["size"] = options["maxlength"] unless options.key?("size")
    options["type"] ||= field_type
    options["value"] = options.fetch("value") { value_before_type_cast(object) } unless field_type == "file"
    options["value"] &&= ERB::Util.html_escape(options["value"])
    add_default_name_and_id(options)
    tag("input", options)
  end

    def value_before_type_cast(object)
      unless object.nil?
        method_before_type_cast = @method_name + "_before_type_cast"

        object.respond_to?(method_before_type_cast) ?
          object.send(method_before_type_cast) :
          value(object)
      end
    end

好的,所以看起来text_field没有直接访问该属性,而是追加_before_type_cast。我read the documentation,但仍然不明白为什么#text_field需要这个?我可以做到这一点,它的确有效:

class Model < ActiveRecord::Base
  attr_accesor :model_atr

  def model_attr
    'redefined'
  end

  def model_attr_before_type_cast
    model_attr
  end
end

如果我重新定义这两种方法,将来我会以某种方式遇到麻烦吗?有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

使用*_before_type_cast的原因可在此commit的说明中找到:

  

为所有输入和文本字段添加了* _before_type_cast。这有助于获得&#34; 100,000&#34;回到基于整数的    +验证,其值通常为&#34; 100&#34;。