[英]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.