立即调用ActiveRecord 39的#relationship_ids = [1,2,3].任何解决方法? [英] Calling ActiveRecord's #relationship_ids = [1,2,3] saves immediately. Any workarounds?

查看:71
本文介绍了立即调用ActiveRecord 39的#relationship_ids = [1,2,3].任何解决方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ActiveRecord的#relationship_ids方法中遇到了一个奇怪的问题(当您声明"has_many"时会自动添加),该方法会立即保存现有记录,这给我带来了一些问题,我想知道是否有人有任何有用的建议

I've come across an oddity in ActiveRecord's #relationship_ids method (that's added automatically when you declare 'has_many'), which saves immediately for existing records, which is causing me some issues, and I wonder if anyone had any useful advice.

我正在运行Rails 2.3.5.

I'm running Rails 2.3.5.

考虑这种简单的情况,其中文章具有多个标签,例如:

Consider this simple scenario, where an article has_many tags, say:

a = Article.first
a.name = "New Name" # No save yet
a.author_id = 1     # No save yet
a.tag_ids = [1,2,3] # These changes are saved to the database
                    # immediately, even if I don't subsequently
                    # call 'a.save'

这让我感到惊讶.在尝试构建预览工具时,这特别导致了问题-我想更新一堆属性,然后在不保存的情况下预览文章-但在这种情况下,即使没有其他字段也可以保存标签更改.

This seems surprising to me. It's specifically causing problems whilst trying to build a preview facility - I want to update a bunch of attributes and then preview the article without saving it - but in this instance the tag changes do get saved, even though no other fields do.

(可能相关的是,如果"a"是一篇新文章,而不是现有文章,那么事情将按照我的预期运行-在我调用"a.save"之前,不会保存任何内容)

(Of possible relevance is that if 'a' is a new article, rather than an existing one, things behave as I'd expect - nothing is saved until I call 'a.save')

我有一个非常讨厌的解决方法-我可以在模型中覆盖tag_ids =方法来代替填充实例变量,然后将相关模型实际保存在before_save回调中.

I have a fairly nasty workaround - I can override the tag_ids= method in my model to instead populate an instance variable, and actually save the related models in a before_save callback.

但是我想知道一种比必须为我想为其创建预览功能的具有has_many关系的每个模型执行此操作更简单的方法.

But I'd love to know of a simpler way than me having to do this for every model with a has_many relationship I'd like to create a preview facility for.

有人有任何修复/解决方法/一般建议吗?谢谢!

Does anyone have any fixes/workarounds/general advice? Thanks!

推荐答案

这是有原因的.称为外键.在具有多个关系的情况下,链接到具有多个模型的信息将作为外键存储在该模型之外.

There's a reason things are this way. It's called foreign keys. In a has many relationship, the information that links to the model that has many is stored outside of that model as a foreign key.

与文章中一样,具有许多标签.将标签链接到商品的信息存储在标签表或联接表中.当您调用文章保存时,您只会保存该文章.

As in Articles, has many tags. The information that links a tag to an article is stored either in the tags table or in a join table. When you call save on an article you're only saving the article.

活动记录会立即修改那些其他记录.除非您正在处理尚未保存的新文章.如果不知道在外键中放置哪个id,Rails将延迟创建/更新关联记录.

Active record modifies those other records immediately. Except in the case where you're working with a new article that hasn't been saved yet. Rails will delay creating/updating the associated records if it doesn't know which id to place in the foreign key.

但是,如果您要修改现有记录,那么您所决定的解决方案实际上就是您可以做的所有事情.甚至有一个使用accepts_nested_attributes_for的骇客,但这确实不值得.

However, if you're modifying existing records, the solution you've decided on is really all that you can do. There's an even uglier hack using accepts_nested_attributes_for, but it's really not worth the effort.

如果您希望将此行为添加到许多模型中,而不是所有模型中,则可能需要考虑编写一个简单的插件来重新定义所需的方法,并在单个类方法调用中添加该回调.看一下act_as_audited之类的来源,看看它是如何完成的.

If you're looking to add this behaviour to many models but not all models, you might want to consider writing a simple plugin to redefine the assigment the method you need and add the call back in a single class method call. Have a look at the source of something like acts_as_audited to see how it's done.

如果您希望将此行为添加到所有模型中,则可以为has_many写一个包装器.

If you're looking to add this behaviour to all models, you can probably write a wrapper for has_many to do that.

这篇关于立即调用ActiveRecord 39的#relationship_ids = [1,2,3].任何解决方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆