提问人:duhaime 提问时间:7/6/2023 最后编辑:duhaime 更新时间:7/6/2023 访问量:72
Rails:确定关联的属性是否刚刚更改
Rails: Determine if attribute on association just changed
问:
我们有一个模型。该模型具有:Zoo
has_many
Animal
Zoo
after_commit :update_animals
def update_animals
animals.each(&:do_update_animal)
end
该模型(其中 a )又具有:Animal
belongs_to
Zoo
def do_update_animal
# here we need to determine whether the `self.zoo.zookeeper` attribute just updated
end
在块内部,我们如何判断与动物关联的 Zoo 实例上的属性是否刚刚更新?Animal#do_update_animal
zookeeper
铌:为了让它工作,我需要更改我在 Zoo 上的块,以表明 Animal 是 Zoo——如果没有该声明,脏 API 就无法工作。所以在动物园里,我需要:has_many
inverse_of
has_many :animals, inverse_of: :zoo
答:
1赞
Les Nightingill
7/6/2023
#1
试试这个:
# zoo.rb
after_commit :update_animals
def update_animals
animals.each { |animal|
animal.do_update_animal
}
end
# animal.rb
include ZookeeperConcern
# zookeeper_concern.rb
def do_update_animal
if zoo.zookeeper_previously_changed? # presumably animal belongs_to :zoo, right?
# do something
else
# do something else
end
end
这使用 ActiveModel::D irty 功能。
评论
0赞
duhaime
7/6/2023
这是个好主意,但我认为它在我们的案例中行不通。在我们的实际案例中,实际上是在许多模型上共享的关注点中提供的,并调用在每个模型上定义的方法,我们需要在该方法中检查 Zoo 是否脏。因此,最好能够从 Animal 运行一种方法来直接识别 Zoo 是否脏/更改,而不必通过方法链向下传递状态。这可能吗?do_update_animal
do_update_animal
Animal
0赞
Les Nightingill
7/6/2023
你真的想确定它是否发生了变化(正如你所指出的),还是与动物相关的特定动物园实例......即 (似乎更有可能,但我对你的应用程序一无所知!Zoo.zookeeper
animal.zoo.zookeeper
0赞
duhaime
7/6/2023
是的,你说得很对,我们想知道与当前 Animal 实例关联的 Zoo 实例上的属性是否发生了变化。我们希望能够理想地从 Animal 实例内部确定这一点(我知道我们可以从 Zoo 内部确定这一点,并按照您的方式传递它,但这会让事情变得有点丑陋)zookeeper
0赞
Les Nightingill
7/6/2023
好的,我更新了我的建议。与最初的建议相比,我对此更新的确定性较低。很想听听你的发现。
0赞
Les Nightingill
7/6/2023
我刚刚检查了...它似乎按照您要求的方式工作......你觉得怎么样?
1赞
Jibran Usman
7/6/2023
#2
我认为,如果您可以将after_commit替换为around_save和around_destroy,那么这种解决方法可能是一个很好的解决方案
动物园.rb:
around_save :update_animals
around_destroy :update_animals
def update_animals
zookeeper_changed = zookeeper_changed?
yield
animals.each { |animal|
animal.do_update_animal(zookeeper_changed)
}
end
Animal.rb:
def do_update_animal(zookeeper_changed = false)
return unless zookeeper_changed
# do something only if zookeeper changed
end
评论