我有以下型号。
class Company < ApplicationRecord
has_many :company_users
has_many :users, :through => :company_users
after_update :do_something
private
def do_something
# check if users of the company have been updated here
end
end
class User < ApplicationRecord
has_many :company_users
has_many :companies, :through => :company_users
end
class CompanyUser < ApplicationRecord
belongs_to :company
belongs_to :user
end
然后我将这些用作种子:
Company.create :name => 'Company 1'
User.create [{:name => 'User1'}, {:name => 'User2'}, {:name => 'User3'}, {:name => 'User4'}]
假设我要更新Company 1用户,我将执行以下操作:
Company.first.update :users => [User.first, User.second]
这将按预期运行,并将在CompanyUser
模型上创建2条新记录。
但是,如果我想再次更新怎么办?就像运行以下命令一样:
Company.first.update :users => [User.third, User.fourth]
这将销毁前2条记录,并在CompanyUser
模型上创建另外2条记录。
问题是我在技术上{strong>更新了 模型,因此如何在Company
模型上使用after_update
方法检测到这些变化?>
但是,更新属性就可以了:
Company
我如何也可以在关联上使用它?
到目前为止,我已经尝试了以下方法,但无济于事:
答案 0 :(得分:0)
我觉得您在问一个错误的问题,因为您必须在不破坏当前关联的情况下更新您的关联。如您所说:
This will destroy the first 2 records and will create another 2 records on CompanyUser model.
知道我会建议您尝试以下代码:
Company.first.users << User.third
这样,您将不会覆盖当前关联。 如果您想一次添加多条记录,请尝试用[]或()将它们包装起来,不确定是否要使用哪一条。
您可以在这里找到文档:https://guides.rubyonrails.org/association_basics.html#has-many-association-reference
希望这会有所帮助。
编辑:
好吧,我认为这不是你真正的问题。
也许有2种解决方案:
#1观察者:
我的工作是您的联接表上的观察者,它负责每次更改CompanyUser时“ ping”您的Company模型。
gem rails-observers
在此观察者内部调用服务,或者您喜欢的任何事情都将使用您想要的值进行操作
class CompanyUserObserver < ActiveRecord::Observer
def after_save(company_user)
user = company_user.user
company = company_user.company
...do what you want
end
def before_destroy(company_user)
...do what you want
end
end
您可以根据需要使用多个回调。
#2保留记录:
事实证明您需要保留记录。也许您应该考虑使用 PaperTrail 或 Audited 之类的宝石来跟踪您的更改。
很抱歉造成混乱。
答案 1 :(得分:0)
您可以为此使用class Company < ApplicationRecord
attr_accessor :user_ids_attribute
has_many :company_users
has_many :users, through: :company_users
after_initialize :assign_attribute
after_update :check_users
private
def assign_attribute
self.user_ids_attribute = user_ids
end
def check_users
old_value = user_ids_attribute
assign_attribute
puts 'Association was changed' unless old_value == user_ids_attribute
end
end
并检查它是否已更改。
puts
现在,关联更改后,您会在控制台中看到消息。
您可以将"([ ])([0-9]\.)"
更改为任何其他方法。
答案 2 :(得分:0)
has_many关系上有一个集合回调before_add,after_add。
class Project
has_many :developers, after_add: :evaluate_velocity
def evaluate_velocity(developer)
#non persisted developer
...
end
end