Ruby on rails 如何查找id与任何数组都不匹配的位置?
我有一个Ruby on rails 如何查找id与任何数组都不匹配的位置?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有一个训练模型,它拥有并属于许多设备模型。我有一些设备的数组。我想查找所有训练,这些训练没有分配任何与设备ID数组匹配的设备 因此,如果我的array=[2,3,5]我希望找到分配的设备ID不包括2、3或5的所有训练 编辑: 假设有五个设备实例,上面的代码返回带有设备.ids1和4(好)的训练,但也返回部分匹配,例如训练设备.id=[1,2],[1,2,3] Workout.joins(:equipment).merge(Equipment.where("id not in(?)",[2,3,
训练
模型,它拥有并属于许多设备
模型。我有一些设备的数组。我想查找所有训练
,这些训练没有分配任何与设备
ID数组匹配的设备
因此,如果我的array=[2,3,5]
我希望找到分配的设备ID不包括2
、3
或5
的所有训练
编辑:
假设有五个设备实例
,上面的代码返回带有设备.id
s1
和4
(好)的训练,但也返回部分匹配,例如训练
设备.id
=[1,2]
,[1,2,3]
Workout.joins(:equipment).merge(Equipment.where("id not in(?)",[2,3,5])).uniq
或
你也可以试试这个,它会找到所有没有任何设备的训练
Workout.includes(:equipment).where("equipments.id not in(?)",[2,3,5])
或
你也可以试试这个,它会找到所有没有任何设备的训练
Workout.includes(:equipment).where("equipments.id not in(?)",[2,3,5])
这是可以改进的,但应该有效:
class Workout < ActiveRecord::Base
scope :without_equipments, lambda{|ids| joins(:equipment).where("equipments.id not in (?)", ids.repeated_permutation(ids.size).map(&:uniq).uniq)}
end
Workout.without_equipments 2,3,5
课堂训练
这可以改进,但应该可以:
class Workout < ActiveRecord::Base
scope :without_equipments, lambda{|ids| joins(:equipment).where("equipments.id not in (?)", ids.repeated_permutation(ids.size).map(&:uniq).uniq)}
end
Workout.without_equipments 2,3,5
课堂训练
这有助于思考查询返回的结果集
Workout.joins(:equipment).where("equipment.id not in(?)",[2,3,5]).uniq
将所有相关设备加入到他们的训练中。如果一项训练链接到4个设备,那么该训练将获得4行。where子句只是将4过滤为一个较小的数字——它不能仅仅因为一个匹配就将它们全部清除
您需要做的是向联接本身添加条件。差不多
select workouts.*
left join equipments_workouts on workout_id = workouts.id and equipment_id in (2,3,5)
where equipment_id is null
应该返回正确的训练(也应该返回一个装备为0的训练,但我不知道这是否是一个考虑因素。)
这是通过尝试加入“坏”设备来实现的。因为它是一个左连接,如果找不到这样的行,那么结果集仍将包含该训练的一行,但equipmnts\u训练的列都设置为null。作为奖励,您不再需要消除重复项
Activerecord没有一种很好的方式来编写这样的查询。joins方法将接受任意SQL片段,但:
Workout.joins("left join equipment_workouts on workout_id = workouts.id and equipment_id in (2,3,5)").
where("equipment_id is null")
您可能会发现
sanitize\u sql
方法对于生成sql片段非常有用它有助于思考查询返回的结果集
Workout.joins(:equipment).where("equipment.id not in(?)",[2,3,5]).uniq
将所有相关设备加入到他们的训练中。如果一项训练链接到4个设备,那么该训练将获得4行。where子句只是将4过滤为一个较小的数字——它不能仅仅因为一个匹配就将它们全部清除
您需要做的是向联接本身添加条件。差不多
select workouts.*
left join equipments_workouts on workout_id = workouts.id and equipment_id in (2,3,5)
where equipment_id is null
应该返回正确的训练(也应该返回一个装备为0的训练,但我不知道这是否是一个考虑因素。)
这是通过尝试加入“坏”设备来实现的。因为它是一个左连接,如果找不到这样的行,那么结果集仍将包含该训练的一行,但equipmnts\u训练的列都设置为null。作为奖励,您不再需要消除重复项
Activerecord没有一种很好的方式来编写这样的查询。joins方法将接受任意SQL片段,但:
Workout.joins("left join equipment_workouts on workout_id = workouts.id and equipment_id in (2,3,5)").
where("equipment_id is null")
您可能会发现
sanitize\u sql
方法对于生成sql片段非常有用I将:设备更改为:设备,并将“id不在…”更改为“id不在…”以运行此操作。但是,它会返回装备id为1和4的训练(良好),但不会返回没有装备id的训练,并且会返回装备id为1和4的训练两次。哦,我认为它是有很多装备的,所以惯例是使用pluraledited,因此,我认为它会发现所有没有任何设备的训练结果是joins方法返回的训练中,数组中只有一个值与Equipment.id匹配。示例:array=[3]正在将训练与设备进行匹配。id=[1,3]和[1,2,3]etcI将:设备更改为:设备,并将“id不在…”更改为“id不在…”以使其运行。但是,它会返回装备id为1和4的训练(良好),但不会返回没有装备id的训练,并且会返回装备id为1和4的训练两次。哦,我认为它是有很多装备的,所以惯例是使用pluraledited,因此,我认为它会发现所有没有任何设备的训练结果是joins方法返回的训练中,数组中只有一个值与Equipment.id匹配。示例:array=[3]正在将训练与设备进行匹配。id=[1,3]和[1,2,3]等感谢您花时间解释您的答案,非常感谢。我试图使用您的SQL语句,如下所示,但遇到SQL错误,您有什么建议吗?很抱歉,我对SQL了解不多<代码>训练。其中(“left join equipment\u workouts on Workout\u id=workouts.id和equipment\u id in(2,3,5),其中equipment\u id为空”)应该是训练。加入(“left join equipment\u workouts…”)。其中(“equipment\u id为空”)
感谢您花时间解释您的答案,非常感谢。我试图使用您的SQL语句,如下所示,但遇到SQL错误,您有什么建议吗?很抱歉,我对SQL了解不多<代码>训练。其中(“训练中的左连接设备训练”\u id=训练。id和(2,3,5)中的设备id,其中设备id为空”)应该是训练。连接(“左连接设备训练…”)。其中(“设备id为空”)