activerecord如何知道执行插入或更新?

rip*_*747 13 ruby-on-rails

也许一些红宝石专家可以在调用save()时了解activerecord如何知道插入或更新.它背后的逻辑是什么?它检查主键是否为空或其他什么,如果是,是否插入,如果不是更新?

Rya*_*igg 23

虽然对某些人说"RTFM"很好,但我更倾向于使用Rails-3-come-out-and-changes-everything响应:

如何在Rails 2.3(又名"今天")中工作

savecreate_or_update看起来像这样的电话:

def create_or_update
  raise ReadOnlyRecord if readonly?
  result = new_record? ? create : update
  result != false
end
Run Code Online (Sandbox Code Playgroud)

您可以忽略此方法的第一行,因为如果记录是只读的,它只会引发错误(通常不是,但在连接的情况下可能是这样).我们在这里感兴趣的是方法内的第二行和第三行.

第二行调用new_record?定义如下:

  # Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false.
  def new_record?
    @new_record || false
  end
Run Code Online (Sandbox Code Playgroud)

并且@new_record当调用initialize(new调用initialize,并给我们一个新对象,这里有一些后台Ruby-fu)方法调用时设置变量.

所以,如果这@new_recordtrue它会打电话create,如果它是假的那么它会打电话update给我们带来你想要的东西,我想.

此外,当您找到一条记录时,它不会调用initialize,因此不会设置@new_record.如果您注意到,后面的代码new_record?@new_record || false,意味着如果@new_record没有设置它将返回false .

比如说你想找到最后一条Forum记录,所以你会这么做Forum.last.

  1. 这将调用类的last方法,该方法Forum继承自ActiveRecord :: Base
  2. last 调用find类方法.
  3. find 电话 find_last
  4. find_last 电话 find_initial
  5. find_initial 电话 find_every
  6. find_every 电话 find_by_sql
  7. find_by_sql电话instantiate

你会在这里看到,这个变化没有@new_record设置,因此获得的任何记录find都不会是新的记录.

希望这有助于您理解.