[英]How to use rails scope or where clause to query OR AND conditions
所以我正在尝试进行如下查询
Car Model
has_many :colors
scope :for_cars, ->(color) { Car.join(:color).where(colors: { name: color}) }
对于green
或blue
汽车,我可以做到这一点。
Car.for_cars(['green', 'blue'])
我想得到green
和blue
汽车,我该怎么做?
我正在使用postgres。
以这种方式查询:
scope :for_cars, ->(color) { Car.joins(:colors).where("colors.name" => color) }
或者 in this way much simpler:-
scope :for_cars, ->(color) { Car.joins(:colors).where("colors.name": color) }
或者 in this way also if this scope is in Car model:-
scope :for_cars, ->(color) { joins(:colors).where("colors.name": color) }
注意: - Tested in Rails 4.2.9
Car.for_cars('green').merge(Car.for_cars('blue'))
这将生成具有两个联接并返回交集的单个查询。 https://apidock.com/rails/v4.2.7/ActiveRecord/SpawnMethods/merge
但是,随着所需颜色数量的增加(连接过多),此方法将无效。
您还可以执行以下操作:
wanted_colors = ['green', 'blue', 'red', 'yellow']
Car.for_cars(wanted_colors).group("cars.id").having("COUNT(colors.id) = #{wanted_colors.size}")
根据您使用的RDBMS,此方法可能会延迟。
在没有范围的情况下,实现此目标的一种方法是在Car上使用方法:
def color_names
colors.map(&:name)
end
def has_all_color_names(has_color_names = [])
(color_names & has_color_names).size == has_color_names.size
end
def self.has_all_color_names(has_color_names = [])
includes(:colors).select { |car| car.has_all_color_names has_color_names }
end
...然后...
Car.has_all_color_names %w(Green Blue)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.