我有一个简单的用户:**为了清晰起见而编辑了一下,以及Sam的建议
class User < ActiveRecord::Base
# <snip other attribs>
has_many :handles
has_one :active_handle, :class_name => "Handle"
validates_each :active_handle, :allow_nil => true do |record, attr, value|
record.errors.add attr, "is not owned by the correct user" unless record.handles.include?(value)
end
end
一个句柄模型:
class Handle < ActiveRecord::Base
belongs_to :user
attr_accessible :user_id
validates :user_id,
:presence => true,
:numericality => true
attr_accessible :name
validates :name,
#etc...
end
现在,我想在设置User.active_handle关联时检查句柄是否由正确的Handle.user_id拥有。我试图在自定义验证中执行此操作,也在User模型的验证方法中执行此操作。两种方式,它与我想要的完全相反,它将句柄的user_id设置为用户进行检查。
我已经走到了尽头,很明显我听不懂东西,谷歌也没有把我带到任何我尚未到过的地方。
ETA:我还试图操纵has_one与条件的关联,这似乎也失败了......
has_one :active_handle,
:class_name => "Handle",
:conditions => ['user_id =?', '#{self.id}']
答案 0 :(得分:0)
如果您是从用户模型进行的,那么您需要将验证添加到用户模型而不是句柄模型,因为用户正在更新。
这是我在验证用户实际属于句柄之前如何激活它。
class Handle < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_many :handles
validates :handle_can_be_active?
def handle_can_be_active?
if self.handles.include?(self.active_handle)
#no problem
else
errors.add_to_base('Must belong to the handle before it can be active!')
end
end
end
答案 1 :(得分:0)
我会对这个问题采取不同的方法;正如你所发现的那样,双重联系是混乱的,难以维持。相反,我在句柄模型中放置了一个活动标志,并在该标志上排序:active_handle
关联:
class User < ActiveRecord::Base
has_many :handles
has_one :active_handle, :class_name => 'Handle', :order => 'handles.active DESC'
end
现在只有一个链接,它与已建立普通has_many :handles
关联(即Handle模型中的user_id
属性)的链接相同。现在找到活动句柄只是找到用户的第一个Handle并设置了活动标志。我会使用:order
而不是:conditions
,因为它会给你一个很好的回退:如果没有该用户的句柄设置了活动标志,Rails将选择一个用作默认值
然后,在你的句柄模型中,你可以有一个相当简单的激活函数:
class Handle < ActiveRecord::Base
# ...stuff...
def activate!
# Pseudocode - sorry!
sql('UPDATE handles SET active = 0 WHERE user_id = ?', self.user_id)
self.active = true
self.save!
end
end
或者,如果您希望能够调用类似user.handles.activate(hdl)
的内容,则可以添加类似于关联扩展名的内容。或user.active_handle = hdl
。还是......
希望这有帮助!