繁体   English   中英

有没有更好的方法使用范围来编写此ActiveRecord Rails 4.2查询?

[英]Is there a better way to write this ActiveRecord Rails 4.2 query using scopes?

因此,我正在构建一个UI,以使用户可以通过动物和/或培训师来为带postgres的Rails 4应用程序找到一个动物园。

有一系列的动物复选框和一系列的教练复选框。 用户可以在训练者和动物部分中选中多个复选框。

这是我用来构建查询的Rails代码

animal_ids = [1, 2, 3]
trainer_ids = [1, 2] 

# OR query - either an animal or trainer can be present to find a zoo
a = Zoo.includes(:animals).where(animals: { id: animal_ids}) 
b = Zoo.includes(:trainers).where(trainers: { id: trainer_ids})
zoos = a+b

这将在控制台中产生4个sql查询。 有没有更有效的方式来编写此代码? 我应该使用具有OR条件的原始sql吗?

模型设置

class Zoo < ActiveRecord::Base 
  has_many :animals, through: zoo_animals
  has_many :trainers, through: zoo_trainers
  has_many :zoo_trainers
  has_many :zoo_animals
end  

class Animal < ActiveRecord::Base
  has_many :zoos, through :zoo_animals
  has_many :zoo_animals
end  

class Trainer < ActiveRecord::Base
  has_many :zoos, through :zoo_trainers 
  has_many :zoo_trainers
end  

class ZooAnimal < ActiveRecord::Base
  belongs_to :animal
  belongs_to :zoo
end

class ZooTrainer < ActiveRecord::Base
  belongs_to :zoo
  belongs_to :trainer
end

是的,您可以自己指定where子句:

Zoo.includes(:animals, :trainers).references(:animals, :trainers).where("animals.id IN (?) OR trainers.id IN (?)", animal_ids, trainer_ids)

您可以定义一个范围来查找zoo

class Zoo < ActiveRecord::Base
  scope :from_animal_and_trainer, -> (animal_ids, trainer_ids) {
    joins(:animals, :trainers).where(Animal.arel_table[:id].in(animal_ids)
                                      .or(Trainer.arel_table[:id].in(trainer_ids)))
  }
end

然后使用它:

animal_ids = [1, 2, 3]
trainer_ids = [1, 2]
zoos = Zoo.from_animal_and_trainer(animal_ids,  trainer_ids)

顺便说一句,这将只生成一个查询,因为我们在上述查询中使用了joins

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM