我有一个客户端模型如下:
class Client < ActiveRecord::Base
has_many :custodians,:dependent => :destroy
我有一个托管模型如下:
class Custodian < ActiveRecord::Base
belongs_to :client
在我的保管人表中,我记录了id = 0,name ='N / A',我想要包含在我的所有collection_selects中,而不管client_id如何。
例如对于client_id = 10我想在collection_select
中进行以下操作Custodian.where('client_id = 10 or client_id = 0')
我知道我可以在我的观点中做到这一点,但我的观点太多,所以不实用。另外,我想在托管人模型或协会上使用更干的方法。我在Custodian模型上尝试过default_scope但无法使其工作。
基本上我正在寻找在每个关联和collection_select中始终包含id = 0的保管人的方法。
答案 0 :(得分:0)
您无法使用has_many
和belongs_to
方法执行所需操作。要实现belongs_to
关系,Custodian
记录必须包含一个client_id
字段。您的逻辑要求custodian_id=0
记录属于许多Client
条记录,因此它必须包含许多client_id
字段,但它只能有一个has_and_belongs_to_many
字段。请参阅Rails指南 - 活动记录关联 - belongs_to Association(http://guides.rubyonrails.org/association_basics.html)
您可以使用Custodian
关系完成所需内容。通过将Client
和has_and_belongs_to_many
模型custodian_id=0
相互建立,您可以将Client
记录归属于许多has_and_belongs_to_many
条记录以及所有记录其他保管人记录只属于一个客户端(即使它们可能属于多个客户端,您的程序逻辑必须只允许它们属于一个。)请参阅上述Rails指南的class Client < ActiveRecord::Base
has_many_and_belongs_to_many :custodians
end
class Custodian < ActiveRecord::Base
has_many_and_belongs_to_many :client
end
部分。需要说明的是,模型的外观如下:
custodian_id=0
另外,由于custodian_id=0
上的特殊情况,您需要使用active_record
回调建立before_validation
记录关系的查找表记录(可能{{1}您创建新的before_create
记录时,或Client
}。
同样,您需要使用:dependent => :destroy
回调实现自己的before_destroy
功能,以保留custodian_id=0
记录并删除所有其他关联的Custodian
记录。您还必须销毁相应的查找表条目。
这听起来像是很多工作,但如果你绝对必须拥有与custodian_id=0
相关联的Client
记录,这是我能看到它完成的唯一方法。您可能想要评估它,这是非常必要的。可能有其他程序逻辑可以让您在不经过此过程的情况下获得类似的结果。
答案 1 :(得分:0)
您可以使用实例或类方法:
#app/models/client.rb
Class Client < ActiveRecord::Base
has_many :custodians,:dependent => :destroy
def inc_zero(id)
where("client_id = ? OR client_id = 0", id)
end
def self.inc_zero_custodians(id)
joins(:custodians).where("client_id = ? OR client_id = 0", id)
end
end
#-> Client.custodians.inc_zero(10)
#-> Client.inc_zero_custodians(10)