在连接事件记录关联时,我经常遇到问题,我希望最终了解导致该问题的原因(而不是仅仅解决它)。
通过parent.children<<将子级与父级关联时,对子级的引用会正确更新自身。如果关系是反向建立的(如果通过 child.parent= 完成),则这不起作用。
为什么会发生这种情况?有没有办法使关系成为双向的?
我过去曾尝试过 inverse_of
但没有成功。我希望是这样,因为我对这里发生的事情还不够了解。
示例:
鉴于这些模型:
class Task < ActiveRecord::Base
belongs_to :batch
attr_accessor :state
end
class Batch < ActiveRecord::Base
has_many :tasks
def change_tasks
tasks.each { |x| x.state = "started" }
end
end
为什么第一个规范失败了,但第二个规范却通过了?我可以通过第一关吗?由于某种原因,我需要在第一个规范中重新加载,但在第二个规范中不需要。
describe "avoiding reload" do
context "when association established via child.parent=" do
it "updates child references" do
b = Batch.create
t = Task.create(batch: b)
b.change_tasks
b.tasks[0].state.should == "started" # passes
t.state.should == "started" # fails!?
t.reload.state.should == "started" # passes, note the reload
end
end
context "when association established via parent.children<<" do
it "updates child references" do
b = Batch.create
t = Task.create
b.tasks << t
b.change_tasks
b.tasks[0].state.should == "started" # passes
t.state.should == "started" # passes
end
end
end
感谢您的帮助。
最佳答案
简短的回答是第一个规范和第二个规范中的对象不同。
在第一个规范中,您有 2 个不同的对象(尝试检查 Rails 控制台):
t.object_id != b.tasks[0].object_id
虽然两个对象都引用相同的记录,但它们是不同的。您已更改 b.tasks[0]
,但 t
在重新加载之前保持不变。
在第二个规范中只有对象:
t.object_id == b.tasks[0].object_id
因此 t
的任何更新都将反射(reflect)在 b.tasks[0]
中,反之亦然。
关于ruby-on-rails - 为什么我需要重新加载这个子关联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14838481/