11

我有一个具有多个 has_many 和 has_many 的模型:通过模型关系。例如,在我的 User 类中,我有:

has_many :languages,通过: :profile_languages

我希望能够使用“User.changes”函数检测何时添加或删除这些属性,该函数返回一个在使用 User.language_ids= 函数调用时已更改的属性数组。

有没有其他人尝试过这样做,或者有这方面的经验?

有关 ActiveModel 更改功能的信息:http: //api.rubyonrails.org/classes/ActiveModel/Dirty.html

编辑:根据要求,这就是我正在做的事情。

在分配用户的属性之后并在保存之前,我正在查看从 .changes 返回的所有值,以便在外部日志中记录所有更改。

所以如果我打电话给 u.name = "new name"

然后 u.changes 返回 {name: ['old name', 'new name']}

但是,当我向用户传递一堆语言 ID 时,例如

u.language_ids = [4,5]

然后创建了许多 ProfileLanguage 模型,并且 u.changes 哈希留空。

我试图在 ProfileLanguage 模型中创建一些回调,这些回调将手动创建某种哈希,但我想知道这是否确实是最好的解决方案。

4

3 回答 3

15

我现在要使用的有点脏的解决方案是向 has_many 函数添加回调:

has_many :languages, through: :profile_languages, 
        :after_add => :language_add, 
        :before_remove => :language_remove

并将此信息添加到自定义哈希中,当我查看 .changes 函数时,将在保存配置文件时检查该哈希。

于 2012-11-09T16:25:13.750 回答
2

我遇到了同样的问题,我试图检查更新模型时是否创建或删除了新关系。

我尝试使用model.relationship.any? { |a| a.changed? },但这仅检测到现有对象的更改,因此它不适用于创建和删除关系。

在寻找解决方案时,我发现这篇非常简短的文章解决了我们的问题:link

使用model.select { |a| a.new_record? || e.marked_for_destruction? }.any?我已经能够获取所有正在创建或销毁的记录。

结合这一点,a.changed?我可以得到我关系中的每一个变化。

于 2016-05-31T13:13:49.563 回答
0

我知道您正在寻求实现基于文本的更改日志,但我建议您通过paper_trailgem 研究完整的对象版本控制,以此作为实现您想要的方法。它根据他们的 README 提供了这个功能

PaperTrail 可以恢复三种类型的关联:Has-One、Has-Many 和 Has-Many-Through。为此,您需要在安装时使用 rails generate paper_trail:install --with-associations 选项或手动创建一个 version_associations 表。当关联记录发生更改时,PaperTrail 将在该表中存储附加信息以关联关联版本和模型版本。

我没有使用 的 has-many-through 特性paper_trail,但是我已经将它用于没有关联的对象,并且发现它非常好并且易​​于实现。

要制作文本文件日志以及此数据库纸迹,您可以在回调中使用paper_trail 的差异功能。after_save

于 2016-06-01T08:59:30.770 回答