after_update 调用依赖于变化的关联方法
after_update calls association's method that depends on the change
简介
我在调用关联方法的回调时遇到问题,但该方法取决于导致回调的更改。即使在 after_update
.
中调用关联,它似乎也看不到变化
场景
一个Nerd
有很多个ProblemSet
,一个ProblemSet
属于一个Nerd
ProblemSet 有一个 status
属性,可以是:
- “发现”- 找到要解决的问题集
- “正在解决”- 目前正在解决问题集
- "已解决" - 完成问题集
书呆子有一个 working
属性,可以是:
true
- ProblemSet
中至少有一个状态为“正在解决”
false
- ProblemSet
中的 none 的状态为“正在解决”
这是模型的样子:
class ProblemSet < ActiveRecord::Base
belongs_to :nerd
after_update :set_nerd_activity
def set_nerd_activity
if status_changed?
self.nerd.set_working
end
end
end
class Nerd < ActiveRecord::Base
has_many :problem_sets
def set_working
update_column(:working, solving_a_problem_set?)
end
def solving_a_problem_set?
self.problem_sets.any? do |ps|
ps.status == "solving"
end
end
end
问题
problemSet.status
=> "finding"
problemSet.update(status: "solving")
problemSet.nerd.working
=> false # I'm expecting this to be true
我认为问题是 nerd
没有看到变化,就好像调用 Nerd#set_status
时更改 ProblemSet's
状态的数据库事务没有完全提交。
我的 rspec 测试 Nerd
和一个 ProblemSet
没有通过。但它们确实适用于 Nerd
和多个 ProblemSet
.
所以我认为这可能是 rspec 的事情。
然后我在控制台中尝试了它,但我仍然看到了问题。我也很小心地使用 .reload
来检查值是否已更新。
我试过使用 after_commit
和 after_save
而不是 after_update
但这打破了对书呆子的多个 ProblemSets
的测试。
知道发生了什么吗?
这种方式应该有效,我在评论中提供的答案有效,因为您正在查询关系之外的对象,这应该使它适用于您的旧代码。
class ProblemSet < ActiveRecord::Base
belongs_to :nerd, inverse_of: :problem_sets
end
class Nerd < ActiveRecord::Base
has_many :problem_sets, inverse_of: :nerd
end
简介
我在调用关联方法的回调时遇到问题,但该方法取决于导致回调的更改。即使在 after_update
.
场景
一个Nerd
有很多个ProblemSet
,一个ProblemSet
属于一个Nerd
ProblemSet 有一个 status
属性,可以是:
- “发现”- 找到要解决的问题集
- “正在解决”- 目前正在解决问题集
- "已解决" - 完成问题集
书呆子有一个 working
属性,可以是:
true
-ProblemSet
中至少有一个状态为“正在解决”false
-ProblemSet
中的 none 的状态为“正在解决”
这是模型的样子:
class ProblemSet < ActiveRecord::Base
belongs_to :nerd
after_update :set_nerd_activity
def set_nerd_activity
if status_changed?
self.nerd.set_working
end
end
end
class Nerd < ActiveRecord::Base
has_many :problem_sets
def set_working
update_column(:working, solving_a_problem_set?)
end
def solving_a_problem_set?
self.problem_sets.any? do |ps|
ps.status == "solving"
end
end
end
问题
problemSet.status
=> "finding"
problemSet.update(status: "solving")
problemSet.nerd.working
=> false # I'm expecting this to be true
我认为问题是 nerd
没有看到变化,就好像调用 Nerd#set_status
时更改 ProblemSet's
状态的数据库事务没有完全提交。
我的 rspec 测试 Nerd
和一个 ProblemSet
没有通过。但它们确实适用于 Nerd
和多个 ProblemSet
.
所以我认为这可能是 rspec 的事情。
然后我在控制台中尝试了它,但我仍然看到了问题。我也很小心地使用 .reload
来检查值是否已更新。
我试过使用 after_commit
和 after_save
而不是 after_update
但这打破了对书呆子的多个 ProblemSets
的测试。
知道发生了什么吗?
这种方式应该有效,我在评论中提供的答案有效,因为您正在查询关系之外的对象,这应该使它适用于您的旧代码。
class ProblemSet < ActiveRecord::Base
belongs_to :nerd, inverse_of: :problem_sets
end
class Nerd < ActiveRecord::Base
has_many :problem_sets, inverse_of: :nerd
end