默认情况下,在任何关联中包含记录

时间:2014-04-15 01:12:19

标签: ruby-on-rails ruby ruby-on-rails-3

我有一个客户端模型如下:

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的保管人的方法。

2 个答案:

答案 0 :(得分:0)

您无法使用has_manybelongs_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关系完成所需内容。通过将Clienthas_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)