在rails中,在新查询中进行查询连接

时间:2014-07-22 21:13:33

标签: ruby-on-rails activerecord

我想要的是与此类似的东西

models = Model0.where( attr: true )
results1 = Model1.joins(models)
results2 = Model2.joins(models)

我知道如果我想

,我可以反过来做
joined1 = Model1.joins(:model0s)
results1 = joined1.where('model0s.attr' => true )
joined2 = Model2.joins(:model0s)
results2 = joined2.where('model0s.attr' => true )

但这意味着我实际上有很多条款的多余的条款。

那么第一个例子是可能的吗?

编辑:

我想动态地这样做。这也是我不想复制信息的原因 目前我的代码更接近。

def filter_model0_by_criteria(model_to_filter, criteria)
    to_filter = model_to_filter.joins(:model0s)
    unless( criteria[:model0_attr1].blank? )
        to_filter = to_filter.where( model0_attr1: criteria[:model0_attr1] )
    end
    unless( criteria[:model0_attr2].blank? )
        to_filter = to_filter.where( model0_attr2: criteria[:model0_attr2] )
    end
    #more conditionals, not all are equals some are > and < etc.
    to_filter
end

def filter_model1_by_criteria(criteria)
    to_filter = self.filter_model0_by_criteria(Model1, criteria)
    unless( criteria[:model1_attr1].blank? )
        to_filter = to_filter.where( model1_attr1: criteria[:model1_attr1] )
    end
    unless( criteria[:model1_attr2].blank? )
        to_filter = to_filter.where( model1_attr2: criteria[:model1_attr2] )
    end
    #more conditionals, not all are equals some are > and < etc.
    to_filter
end

def filter_model2_by_criteria(criteria)
    to_filter = self.filter_model0_by_criteria(Model2, criteria)
    unless( criteria[:model2_attr1].blank? )
        to_filter = to_filter.where( model2_attr1: criteria[:model2_attr1] )
    end
    unless( criteria[:model2_attr2].blank? )
        to_filter = to_filter.where( model2_attr2: criteria[:model2_attr2] )
    end
    #more conditionals, not all are equals some are > and < etc.
    to_filter
   end

results1 = self.filter_model1_by_criteria( criteria )
results2 = self.filter_model2_by_criteria( criteria )

所以这里有两种冗余,逻辑和条款。

2 个答案:

答案 0 :(得分:0)

你能做的是

class Model1 < ActiveRecord::Base
  has_many :attr_model0s, -> { where attr: true }, :class_name => "Model0"
end

class Model2 < ActiveRecord::Base
  has_many :attr_model0s, -> { where attr: true }, :class_name => "Model0"
end

Model1.joins(:attr_model0s)
Model2.joins(:attr_model0s)

答案 1 :(得分:0)

原来最接近我想要的是合并 http://api.rubyonrails.org/classes/ActiveRecord/SpawnMethods.html#method-i-merge

所以使用我的初始例子

models = Model0.where( attr: true )
results1 = Model1.joins(:model0s).merge(models)
results2 = Model2.joins(:model0s).merge(models)