Rails - 如何在保存后刷新关联

Posted

技术标签:

【中文标题】Rails - 如何在保存后刷新关联【英文标题】:Rails - How to refresh an association after a save 【发布时间】:2012-09-22 14:29:52 【问题描述】:

我有一个包含项目列表的类别。项目有一个位置,类别有一个关系 has_many :items, :order => "position"。当用户更新位置值时,我想查看它的位置。我的位置是一个浮点数,允许在四舍五入的数字之间移动。

pos=item.category.items.map(&:id)
current_position=pos.index(id.to_i)
item.save # want to refresh the relationship here
pos_new=item.categoty.items.map(&:id)
# grabbing this since just accessing item isn't updated if positioning has changed
item_new=Item.find(id)
pos_new=item_new.category.items.map(&:id)
new_position=pos_new.index(id)
if current_position!=new_position
  is_moved=true # sent back in JSON to propagate a dynamic change.
end

上述方法有效,但似乎非常冗长。有没有办法让我告诉项目保存需要刷新类别关系,因为订单可能会更改?

【问题讨论】:

【参考方案1】:

您可以使用item.reload 从数据库中重新获取模型,并且下次调用关联时,它会重新获取它。

【讨论】:

【参考方案2】:

Rails 4 将在您的 has_many/belongs_to 关联对象发生更改时为您更新它们,但它不会重新运行查询,这意味着即使 category.items 中的项目将被更新,它们也不会按顺序排列。根据表的大小,您可能希望使用 ruby​​ 对结果进行排序或使用 category.reload 将它们按顺序排列。

请参阅 http://guides.rubyonrails.org/association_basics.html 的 RailsGuides 并查找 inverse_of

【讨论】:

【参考方案3】:

对于单项关联:

book.reload_author

对于其他关联:

author.books.reload

http://guides.rubyonrails.org/association_basics.html#controlling-caching


在 Rails 5 之前的旧版本 Rails 中,您可以将 true 作为第一个参数传递给关联方法以使其重新加载:author.books(true)

【讨论】:

谁仍然从搜索中得到这个答案(就像我刚才所做的那样):rails 不再支持这种行为。您会收到弃用警告。集合的新方法是在集合代理上使用reload 方法。 @klaustopher 谢谢。更新了我的答案。 "弃用警告:现在不推荐使用传递参数来强制重新加载关联,并将在 Rails 5.1 中删除。请改为在父对象上调用 reload。(从
调用(撬):2)“
我们为什么要手动调用这个重载?反正没有自动做吗?谢谢 @newBike 您手动调用它是因为您而不是 Rails 知道何时需要它。您可能会在内存中设置模型的值并稍后保存,但重新加载会破坏您的更改并将其重新设置。此外,当您更新值然后保存时,您已经在内存中的对象中拥有更新的数据,因为您只是在数据库获得值之前设置它。

以上是关于Rails - 如何在保存后刷新关联的主要内容,如果未能解决你的问题,请参考以下文章

Rails gem Ratyrate 仅在刷新后显示星星而不是保存

在 Rails 应用程序中单击 link_to 标记后如何使用 JS 刷新浏览器

如何在rails中保存包含另一个模型属性的模型?

Rails - 如何让两个用户 ID 与模型相关联

Rails如何在保存后更新列?

Rails 6 + Webpack + jQuery 刷新时不保存更改