如何从 Rails 中的查询中排除 id 数组(使用 ActiveRecord)?

Posted

技术标签:

【中文标题】如何从 Rails 中的查询中排除 id 数组(使用 ActiveRecord)?【英文标题】:How to exclude an array of ids from query in Rails (using ActiveRecord)? 【发布时间】:2011-06-02 15:43:45 【问题描述】:

我想执行一个 ActiveRecord 查询,该查询返回除具有特定 ID 的记录之外的所有记录。我想排除的 id 存储在一个数组中。所以:

ids_to_exclude = [1,2,3]
array_without_excluded_ids = Item. ???

我不确定如何完成第二行。

背景:我已经尝试过的:

我不确定背景是否必要,但我已经尝试过 .find 和 .where 的各种组合。例如:

array_without_excluded_ids = Item.find(:all, :conditions =>  "id not IN (?)", ids_to_exclude )
array_without_excluded_ids = Item.where( "items.id not IN ?", ids_to_exclude)

这些都失败了。 This tip 可能在正确的轨道上,但我还没有成功适应它。任何帮助将不胜感激。

【问题讨论】:

你试过:conditions => [ "id not IN (?)", ids_to_exclude ]吗?注意括号而不是大括号。 在 Rails 3.2.1 中,我最近在查询中使用了这个 MyModel.order('created_at DESC').where('id NOT in (?)', ids_to_exclude).limit(5) 【参考方案1】:

Rails 4 解决方案:

ids_to_exclude = [1,2,3]
array_without_excluded_ids = Item.where.not(id: ids_to_exclude)

【讨论】:

这是目前最好的选择。【参考方案2】:

这应该可行:

ids_to_exclude = [1,2,3]
items_table = Arel::Table.new(:items)

array_without_excluded_ids = Item.where(items_table[:id].not_in ids_to_exclude)

而且它完全面向对象,没有字符串 :-)

【讨论】:

Arel::Table 是数据库表的抽象,包含一组列。在我的系统上,我使用的是 PostgreSQL,所以该列的类型是 ActiveRecord::ConnectionAdapters::PostgreSQLColumn,它代表了我的数据库列的特征。每列包含列的名称、该列的 DB 类型、默认值、比例、精度特征等。我们需要一个 Table 实例来对 ID 列进行谓词匹配。 'not_in' 方法的类型是 Arel::Predicates,它会直接转换为您想要的 SQL,例如“不在 (1, 2, 3) 中”。 @sinisterchipmunk 这是因为为空数组生成的 SQL 将是 SELECT "Items".* FROM "items" WHERE "items"."id" NOT IN (NULL)。与 NULL 的匹配是 UNKOWN。这是一个三值逻辑问题:en.wikipedia.org/wiki/Three-valued_logic 更漂亮的语法:Item.where(Item.arel_table[:id].not_in ids_to_exclude) @marczking 字符串?呃……我觉得恶心;去躺下。 这太棒了。我的用例是每周一次的订单导出,其中包含一些疯狂的数据映射,因为我们的会计已经发展了很长一段时间......我真的需要我的查询作为活动返回记录关系,因为我使用 .to_csv 类方法将我的电子商务订单映射到 csv。由于某种原因,它不适用于数组或 Order 对象,只能用于活动记录关系。我一辈子都想不出如何在我的 .where 活动记录 SQL 查询中打印我们的 id 数组,作为逗号分隔的列表。谢谢斯科特·洛 ^_^【参考方案3】:

您也可以使用Squeel gem 来完成这样的查询。 它的文档,去here

【讨论】:

【参考方案4】:

正如 nslocum 所写,以下内容运行良好:

Item.where.not(id: ids_to_exclude)

如果您的“要排除的 ID”来自查询(此处带有示例条件),您甚至可以更进一步:

Item.where.not(id: Item.where(condition: true))

如果您需要过滤另一个模型,这很有用:

OtherModel.where.not(item_id: Item.where(condition: true))

【讨论】:

以上是关于如何从 Rails 中的查询中排除 id 数组(使用 ActiveRecord)?的主要内容,如果未能解决你的问题,请参考以下文章

使用jQuery从数组数组动态生成<table>时如何排除ID列

Rails,ActiveRecord,在int数组中查询id,保持传递数组的顺序

如何使用 findOne 查询 mongodb 并排除数组中的一些嵌套字段

如何使 .populate 排除空值?

如何从数组中排除空数组?

从 heroku slugs 中排除 gems 中的文件(使用 .slugignore、heroku)