调用的ActiveRecord的#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.
考虑一个简单的场景,其中一篇文章的has_many标签,说:
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'
这似乎令我感到诧异。它是专门造成的问题,而试图建立一个preVIEW设施 - 我想更新了一堆的属性,然后preVIEW文章,而不保存它 - 但在这种情况下,标签的更改都得到保存,即使没有其他领域做的。
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关系,我想创建一个preVIEW设施适合我。
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.
活动记录,立即修改这些其他记录。除非在你正在使用已尚未保存的新条款的情况。 Rails会推迟创建/更新相关记录,如果它不知道在国外键将其ID。
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.
如果你想添加这个行为,很多车型,但并非所有的车型,你可能要考虑编写一个简单的插件来重新定义assigment你所需要的方法,并添加回调在一个类中的方法调用。看一看的类似acts_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.