【问题标题】:Detecting changes in a rails has_many :through relationship检测rails has_many中的变化:通过关系
【发布时间】:2012-10-29 07:39:26
【问题描述】:

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

has_many :languages, through: :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 模型中创建一些回调,这些回调将手动创建某种哈希,但我想知道这是否确实是最好的解决方案。

【问题讨论】:

  • 嗨,Ron,你能把你的问题说得更具体一点吗?也许向我们展示你到目前为止的设置,这样我们就有了一些事情要做。
  • 你研究过回调或观察者吗?
  • 添加了一个编辑。希望它可以澄清

标签: ruby-on-rails ruby-on-rails-3 has-many-through


【解决方案1】:

我知道您正在寻求实现基于文本的更改日志,但我建议您通过 paper_trail gem 研究完整的对象版本控制,以此作为实现您想要的方法。它提供this functionality according to their README

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

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

要制作文本文件日志以及此数据库文件记录,您可以在 after_save 回调中使用 paper_trail's diff features

【讨论】:

    【解决方案2】:

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

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

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

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

    将此与a.changed? 结合起来,我可以得到我关系中的每一个变化。

    【讨论】:

    • 适用于accepts_nested_attributes_for,但一般不适用。
    • 你把这个放在哪里了?我正在尝试在 after_update 回调上使用它。
    【解决方案3】:

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

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

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

    【讨论】:

    • 这对我不起作用。看来,当您进行批量分配时(就像 op 对 language_ids 所做的那样),不会触发 after_add 和 before_remove 回调。我做错了吗?
    • 它有效,然后为每个删除对象分别调用这些回调。
    • 很好的解决方案,从来没有听说过这两个回调。它还将删除的元素作为属性发送给回调方法。
    猜你喜欢
    • 2020-04-12
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多