Rob*_*Rob 5 ruby activerecord ruby-on-rails associations ruby-on-rails-4
我在这里做了一个真实的基本github项目来演示这个问题。基本上,当我创建新评论时,它会按预期保存;更新现有评论时,不会保存它。但是,这并不是文档:autosave => true所说的……他们说的恰恰相反。这是代码:
class Post < ActiveRecord::Base
has_many :comments,
:autosave => true,
:inverse_of => :post,
:dependent => :destroy
def comment=(val)
obj=comments.find_or_initialize_by(:posted_at=>Date.today)
obj.text=val
end
end
class Comment < ActiveRecord::Base
belongs_to :post, :inverse_of=>:comments
end
Run Code Online (Sandbox Code Playgroud)
现在在控制台中,我测试:
p=Post.create(:name=>'How to groom your unicorn')
p.comment="That's cool!"
p.save!
p.comments # returns value as expected. Now we try the update case ...
p.comment="But how to you polish the rainbow?"
p.save!
p.comments # oops ... it wasn't updated
Run Code Online (Sandbox Code Playgroud)
为什么不?我想念什么?
请注意,如果您不使用“ find_or_initialize”,则它会因为ActiveRecord尊重关联缓存而起作用-否则,它会过于频繁地重新加载注释,从而导致更改。即,此实现有效
def comment=(val)
obj=comments.detect {|obj| obj.posted_at==Date.today}
obj = comments.build(:posted_at=>Date.today) if(obj.nil?)
obj.text=val
end
Run Code Online (Sandbox Code Playgroud)
但是,当然,如果我可以对数据库进行操作,则我不想遍历内存中的集合。另外,似乎与新对象兼容但不适用于现有对象。
这是另一种选择。find_or_initialize_by如果返回的记录不是新记录,则可以将其显式添加到集合中。
def comment=(val)
obj=comments.find_or_initialize_by(:posted_at=>Date.today)
unless obj.new_record?
association(:comments).add_to_target(obj)
end
obj.text=val
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
771 次 |
| 最近记录: |