问题描述
说我有这两个班
class Gadget < ActiveRecord::Base
has_many :widgets
end
class Widget < ActiveRecord::Base
belongs_to :gadget
# table has string attribute .color
end
假设数据库包含一个小工具和一个小部件,每个小部件都带有id = 1
,并且该小部件的颜色为nil
。
修改通过.find
检索到的记录
g = Gadget.first
w = g.widgets.find { |widg| widg.id == 1 }
w.color = "blue"
g.widgets.first.color
=> "blue"
修改通过.find_by
检索到的记录
g = Gadget.first
w = g.widgets.find_by(id: 1)
w.color = "blue"
g.widgets.first.color
=> nil
我无法解释这种差异。
解决方法
如果使用find_by
方法,rails将find_by语句添加到查询的末尾,因此将只有一条记录加载到内存中(如果有),并且DB可以在此处找到该记录。如果对块使用find
方法,rails首先将所有小部件加载到内存中,然后它将为给定语句搜索特定的小部件,这将导致额外的内存使用,因为DB可以完成相同的工作。另外,如果您像这样使用find
方法:g.widgets.find(1)
,将与g.widgets.find_by(id: 1)
方法相同。