在我意识到发生了什么事之前,我一直在努力解决问题。
我想建立一个必须至少有一名成员的委员会。为此,每个成员在被销毁之前检查它不是最后一个成员。
下面的代码应该可以防止最后一个成员被摧毁,除非委员会本身被摧毁,在这种情况下它会自我毁灭。
class Committee < ActiveRecord::Base
has_many :committee_members
before_destroy: { @destroy_initiated = true }
def destroy_initiated?
@destroy_initiated
end
end
class CommitteeMember < ActiveRecord::Base
belongs_to :committee
before_destroy :ensure_not_last
def ensure_not_last
unless self.committee.destroy_initiated?
if self.committee.committee_members.count == 1
raise 'You cannot remove the last committe member. Try destroying the committee instead'
end
end
end
end
问题
问题是每个委员会成员都引用了委员会对象的不同实例,它们都有不同的对象标识:
e.g。 #<Committee:0x00000105c41f20>
v。#<Committee:0x00000105c2c3a0>
这意味着即使我在ID为20的委员会实例上设置@destroy_initiated为true,也不会在其委员会成员引用的实例上将其设置为true。
除了Rails 3.1,我知道它有一个身份图,是否有一个干净的解决方法,有一个实例变量,可用于委员会的所有实例?
我正在考虑做一个包含destroy_initiated地图的类变量?每个委员会ID,但这感觉非常混乱。
答案 0 :(得分:0)
我不确定我是否可以在没有更多背景的情况下正确回答这个问题,但我可以给你一个可能的解决方案来思考......
在我刚刚投入生产的应用程序中,我们实际上将对象缓存为ApplicationController上的实例变量。然后,只要我们需要它,我们只需要实例变量而不是使用Active Record查找它。
class ApplicationController < ActionController::Base
before_filter :set_committee
def set_committee
@committee ||= Committee.new()
end
end
现在,在请求期间,从ApplicationController继承的任何内容都可以访问@committee对象。如果您可以使用类似的模式(不必是应用程序控制器,可以只是任何其他控制器),那么在请求期间您基本上会有一个“全局”变量。