Ruby on rails Ruby(2.2.9版)需要在关联更改时触发方法
我有一门课:Ruby on rails Ruby(2.2.9版)需要在关联更改时触发方法,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我有一门课: class Foo < ActiveRecord::Base has_and_belongs_to_many :bar after_save :do_the_thing #hoping when bars are changed, Foo fires do_the_thing def do_the_thing #Something happens here end end class Foo
class Foo < ActiveRecord::Base
has_and_belongs_to_many :bar
after_save :do_the_thing #hoping when bars are changed, Foo fires do_the_thing
def do_the_thing
#Something happens here
end
end
class Foo
但是,当
foo
和bar
之间的关联发生变化时(例如,与foo
关联的bar
被删除,添加到现有foo,或者从一个foo移动到另一个foo?),它不会触发foo
的变化。当关联发生变化时,如何让foo
的方法触发?我认为,如果您想对栏中的变化做出反应(例如删除),您需要在那里添加回调,例如
class Bar < ActiveRecord::Base
has_and_belongs_to_many :foos
after_destroy :notify_foos_destroyed
after_save :notify_foo_save
def notify_foos_destroyed
foos.each{|foo| foo.call_a_method}
end
def notify_foos_saved
foos.each{|foo| foo.call_another_method}
end
end
类栏
编辑:
如果要对分配更改做出反应,需要向链接模型添加回调:
class Bar < ActiveRecord::Base
has_many :foos, through: :foo_bar_link
has_one :foo_bar_link
end
class Foo < ActiveRecord::Base
has_many :bars, through: :foo_bar_link
has_one :foo_bar_link
end
class FooBarLink < ActiveRecord::Base
self.table_name = 'foo_bar_linking_table'
belongs_to :bar
belongs_to :foo
after_save :notify
def notify(*)
bar.call_a_method
foo.call_a_method
end
end
类栏
如果您使用has\u many to:
而不是has\u和\u belien\u many
与一起使用,那么这就非常简单了
两者都创建多对多关联。但是拥有并且属于许多
只处理零复杂性的情况。有关详细说明,请参阅
class Foo < ApplicationRecord
has_many :foo_bars
has_many :bars, through: :foo_bars, after_add: :do_the_thing
def do_the_thing(bar)
puts "Doing da thang"
end
end
class FooBar < ApplicationRecord
belongs_to :foo
belongs_to :bar
end
class Bar < ApplicationRecord
has_many :foo_bars
has_many :foos, through: :foo_bars
end
class Foo
irb(main):001:0>foo=foo.create
(0.3ms)开始
SQL(1.2ms)插入“foos”(“创建时间”,“更新时间”)值($1,$2)返回“id”[[“创建时间”,2019-10-11 21:31:54 UTC],“更新时间”,2019-10-11 21:31:54 UTC]]
(0.6ms)提交
=> #
irb(主):002:0>foo.bar.create
(0.1ms)开始
SQL(0.6ms)插入“条”(“创建时间”,“更新时间”)值($1,$2)返回“id”[[“创建时间”,2019-10-11 21:32:00 UTC],“更新时间”,2019-10-11 21:32:00 UTC]]
SQL(1.8ms)插入“foo_bar”(“foo_id”、“bar_id”、“created_at”、“updated_at”)值($1、$2、$3、$4),返回“id”[[“foo_id”,6],“bar_id”,5],“created_at”,2019-10-11 21:32:00 UTC],“updated_at”,2019-10-11 21:32:00 UTC]]
做大唐
(0.7毫秒)提交
=> #
。。。如果一个条从一个foo移动到另一个foo,会不会触发此事件?实际上,在本例中不会,因为它会导致链接模型上的保存。您可以显式定义链接模型并添加回调,而不是使用hbtm。该模型将归属于:foo
和归属于:bar
。Foo和bar将有一个:Foo\u bar\u link
和有许多:Foo到
这是在一个运行了一段时间的代码库上,这会破坏ActiveRecord创建的现有链接吗?如果您使用self.table\u name=“name\u of\u the\u linking\u table”将链接模型设置为使用现有表,则不会在答案中加入这个选项,我会接受它。你想要的是。不确定它们是否可用于has\u和\u属于\u many
,这与has\u many到:
相比是相当有限的。我将试一试,以防万一。不幸的是,没有这种方法。我猜它不在has上,并且属于\u many然后使用has\u many通过:
-它做完全相同的事情,但限制较少。
irb(main):001:0> foo = Foo.create
(0.3ms) BEGIN
SQL (1.2ms) INSERT INTO "foos" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", 2019-10-11 21:31:54 UTC], ["updated_at", 2019-10-11 21:31:54 UTC]]
(0.6ms) COMMIT
=> #<Foo id: 6, created_at: "2019-10-11 21:31:54", updated_at: "2019-10-11 21:31:54">
irb(main):002:0> foo.bars.create
(0.1ms) BEGIN
SQL (0.6ms) INSERT INTO "bars" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", 2019-10-11 21:32:00 UTC], ["updated_at", 2019-10-11 21:32:00 UTC]]
SQL (1.8ms) INSERT INTO "foo_bars" ("foo_id", "bar_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["foo_id", 6], ["bar_id", 5], ["created_at", 2019-10-11 21:32:00 UTC], ["updated_at", 2019-10-11 21:32:00 UTC]]
Doing da thang
(0.7ms) COMMIT
=> #<Bar id: 5, created_at: "2019-10-11 21:32:00", updated_at: "2019-10-11 21:32:00">