是否在 HABTM 关系中的联接表中调用 ActiveRecord 回调?

Posted

技术标签:

【中文标题】是否在 HABTM 关系中的联接表中调用 ActiveRecord 回调?【英文标题】:Are ActiveRecord callbacks called in the join table in an HABTM relationship? 【发布时间】:2012-02-23 16:14:42 【问题描述】:

在测试acts_as_audited 时,我发现(也如here 所述):with_associations 标志不会为 HABTM 关系生成审计表条目。

例如:

User < ActiveRecord::Base
  has_and_belongs_to_many: :groups
  acts_as_audited, with_associations: groups

Group < ActiveRecord::Base
  has_and_belongs_to_many: :users
  acts_as_audited, with_associations: users

(以及经过测试的变体,即有/无 with_associations)

在源代码中,可以看到所有acts_as_audited 所做的只是将诸如 before_update 和 after_create 之类的回调添加到已审核的表中。显然这些没有添加到连接表中。

我尝试制作这样的模型:

GroupsUsers < ActiveRecord::Base
  acts_as_audited

  after_save: :test

  def test
    logger.debug "test"
  end

但没有看到对用户或组的 CRUD 操作的审计表有任何添加。我可以在日志中看到作用于连接表的 SQL 语句,因此这表明连接表在内部以绕过正常回调的方式进行了更改。

这是真的吗?关于让acts_as_audited 注意到连接表或记录HABTM 关联的任何建议?

【问题讨论】:

这更像是 Rails 问题而不是acts_as_audited 问题——Rails 不会对某些HABTM 生成的方法运行回调,因此acts_as_audited 不会捕捉到发生的情况。您如何更新关联? @MatthewLehner,这是我想知道的事情之一。这是否意味着连接表中的 CRUD 操作在某种程度上与数据表有根本的不同?为什么我不能为连接表创建一个骨架模型类并使用回调以通常的方式跟踪它的 CRUD 操作?例如,这篇文章表明这​​是可能的:robots.thoughtbot.com/post/159808010/… 【参考方案1】:

关联回调has_and_belongs_to_many

与挂钩到 Active Record 对象生命周期的普通回调类似,您还可以定义在向关联集合中添加对象或从关联集合中删除对象时触发的回调。

class Project
  has_and_belongs_to_many :developers, after_add: :evaluate_velocity

  def evaluate_velocity(developer)
    ...
  end
end

可以通过将回调作为数组传递来堆叠回调。示例:

class Project
  has_and_belongs_to_many :developers,
                          after_add: [:evaluate_velocity, Proc.new  |p, d| p.shipping_date = Time.now]
end

可能的回调有:before_addafter_addbefore_removeafter_remove

如果任何before_add 回调抛出异常,该对象将不会被添加到集合中。

同样,如果任何before_remove 回调抛出异常,该对象将不会从集合中移除。

【讨论】:

以上是关于是否在 HABTM 关系中的联接表中调用 ActiveRecord 回调?的主要内容,如果未能解决你的问题,请参考以下文章

在 hasAndBelongsToMany (HABTM) Cakephp 方面需要帮助

尝试在保存时保存 CakePHP HABTM 关系中的重复关联

Rails,Ransack:如何在 HABTM 关系中搜索“所有”匹配项而不是“任何”匹配项

我可以在多对多关系的联接表中添加非 Id 字段吗?

Rails 搜索 HABTM 关系中的关联模型

CakePHP 2.5 habtm 不保存