在Rails中,ActiveRecord :: Base.new用于实例化尚未保存到数据库的新记录:
new_user = User.new(name: "Bob") new_user.new_record? # => true
那么Rails如何实例化从数据库中检索的记录呢?它是否使用相同的新方法,然后在事后更改@new_record之类的值?或者它是否对从数据库中检索的记录使用某种特殊的实例化方法?
解决方法
new_record?方法可以在ActiveRecord框架中的active_record / persistence.rb中找到,它看起来像这样:
def new_record? @new_record end
然后,如果你在构造函数中查看active_record / core.rb,你会看到:
def initialize(attributes = nil,options = {}) @attributes = self.class.initialize_attributes(self.class.column_defaults.deep_dup) @columns_hash = self.class.column_types.dup init_internals # here ensure_proper_type populate_with_current_scope_attributes assign_attributes(attributes,options) if attributes yield self if block_given? run_callbacks :initialize if _initialize_callbacks.any? end
如果我们在代码中深入挖掘一下:
def init_internals pk = self.class.primary_key @attributes[pk] = nil unless @attributes.key?(pk) @aggregation_cache = {} @association_cache = {} @attributes_cache = {} @prevIoUsly_changed = {} @changed_attributes = {} @readonly = false @destroyed = false @marked_for_destruction = false @new_record = true # here @mass_assignment_options = nil end
如您所见,默认情况下@new_record初始化为true.
但是,有些情况下@new_record属性设置为true,就像克隆记录时一样:
user = User.first new_user = user.clone
def initialize_dup(other) # :nodoc: # Code removed @new_record = true # Code removed super end
或者当ActiveRecord从数据库中提取记录时.我不确定这部分,但我认为这个方法被称为:
def init_with(coder) @attributes = self.class.initialize_attributes(coder['attributes']) @columns_hash = self.class.column_types.merge(coder['column_types'] || {}) init_internals @new_record = false run_callbacks :find run_callbacks :initialize self end
可以这样做:
post = Post.allocate post.init_with('attributes' => { 'title' => 'hello world' })
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。