ruby on rails-默认情况下,在任何关联中都包含一条记录



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

class Client < ActiveRecord::Base
has_many :custodians,:dependent => :destroy

我有一个托管人模型如下:

class Custodian < ActiveRecord::Base
belongs_to :client

在我的保管人表中,我有一个id=0、name="N/A"的记录,我想将其包括在我的所有collection_selections中,而不考虑client_id。

例如,对于client_id=10,我希望在collection_select 中包含以下内容

Custodian.where('client_id = 10 or client_id = 0') 

我知道我可以根据自己的观点来做,但我的观点太多了,所以不实用。另外,我想在托管人模型或协会上有一个更DRY的方法。我在托管人模型上尝试了default_scope,但无法使其工作。

基本上,我正在寻找一种方法,在每个关联和collection_select中始终包含id为0的保管人。

使用has_manybelongs_to方法无法执行您想要的操作。要实现belongs_to关系,Custodian记录必须具有单个client_id字段。您的逻辑要求custodian_id=0记录属于许多Client记录,因此它必须有许多client_id字段,但只能有一个。请参阅Rails指南活动记录关联下面的关联(http://guides.rubyonrails.org/association_basics.html)

您可以使用has_and_belongs_to_many关系来完成您想要的任务。通过使CustodianClient模型has_and_belongs_to_many相互对应,您将能够使custodian_id=0记录属于许多Client记录,而所有其他托管记录将只属于一个客户端(即使它们可能属于多个客户端,但您的程序逻辑必须只允许它们属于一个。)请参阅上述Rails指南的has_and_belongs_to_many部分。需要明确的是,以下是您的模型的外观:

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的特殊情况,在创建新的Client记录时,需要使用active_record回调(可能是before_validationbefore_create)为custodian_id=0记录关系建立查找表记录。

类似地,您需要使用before_destroy回调来实现自己的:dependent => :destroy功能,以保留custodian_id=0记录并删除所有其他关联的Custodian记录。您还必须销毁相应的查找表条目。

这听起来是一项艰巨的工作,但如果你绝对必须将custodian_id=0记录与每个Client关联起来,这是我能看到的唯一方法。你可能想评估一下,这真的很有必要。可能还有其他程序逻辑可以让你在不经过这个过程的情况下获得类似的结果。

您可以使用实例或类方法:

#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)

最新更新