也许有些红宝石专家可以在调用save()时了解activerecord如何知道插入或更新。它背后的逻辑是什么?它是否检查主键是否为空或某些内容,如果是,那么是否为更新?
答案 0 :(得分:23)
虽然对某些人说“RTFM”很好,但我更倾向于使用Rails-3-come-out-and-changes-everything响应的更多步骤但仍然完全无用:
它如何在Rails 2.3中工作(又名“今天”)
save
调用create_or_update
,如下所示:
def create_or_update
raise ReadOnlyRecord if readonly?
result = new_record? ? create : update
result != false
end
您可以忽略此方法的第一行,因为如果记录是只读的,它只会引发错误(通常不是,但在连接的情况下可能是这样)。我们感兴趣的是方法中的第二行和第三行。
第二行调用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
当initialize
(@new_record
调用new
,并为我们提供一个新对象,这里有一些后台Ruby-fu)方法时,设置变量initialize
因此,如果此@new_record
为true
,则会调用create
,如果它为假,则会调用update
,这会将我们带到您所追求的内容,我认为
此外,当您找到记录时,它不会调用initialize
,因此不会设置@new_record
。如果您注意到,new_record?
后面的代码是@new_record || false
,这意味着如果未设置@new_record
,它将返回false。
例如,假设您要查找最后一条Forum
条记录,那么您可以执行Forum.last
。
Forum
类的last
方法last
calls find
类方法。find
calls find_last
find_last
calls find_initial
find_initial
calls find_every
find_every
calls find_by_sql
find_by_sql
来电instantiate
您会在此处看到此更改无处设置@new_record
,因此find
获取的任何记录都不会成为新记录。
希望这有助于您理解。
答案 1 :(得分:2)
它主要依赖于new_record?方法 如果它是新记录,则此方法返回true,如果不是,则返回false。
事实上,这并不是很难。
new_record?
可以直接返回false。Model.new
)时,new_record?
将返回true。这是一项新纪录。@new_record
会更新。 new_record?
将不再返回true。要查看何时发生,请转到ActiveRecord::Base第2911行
self.id ||= new_id
@new_record = false
id
end
答案 2 :(得分:1)