活动记录检查属性是否在基于另一个属性的数组中

时间:2018-09-20 16:45:36

标签: ruby-on-rails ruby postgresql activerecord ruby-on-rails-5

在我的Ruby on Rails项目中,我有一个Message模型,该模型的属性direction为“传入”或“传出”。 Message的另一个属性是body,它表示消息的实际内容。我正在使用Rails 5.1.2。

现在,我要选择消息,同时排除正文位于数组中的传入消息,例如['a','b','c']

例如,如果我的数据库中包含以下消息:

{direction: 'outgoing', body: 'a'}
{direction: 'outgoing', body: 'b'}
{direction: 'outgoing', body: 'd'}
{direction: 'incoming', body: 'd'}
{direction: 'incoming', body: 'c'}

我只希望选择除最后一条以外的消息,即{direction: 'incoming', body: 'c'}

我尝试过

Message.where.not(["direction = ? and body != ?","incoming","['a','b','c']"])仅向我返回传出消息,但缺少正文为“ d”的传入消息。

有什么建议吗? 谢谢。

2 个答案:

答案 0 :(得分:1)

按照文章中提到的描述,您要在数组对象上使用sql拒绝元素。

为此,修改查询以接受数组作为参数,而不是后文提到的字符串。

Message.where.not("direction = ? and body IN (?)","incoming",['a','b','c'])

答案 1 :(得分:1)

而不是!=,我认为您正在寻找IN()语法来匹配正文中的匹配项。

   [25] pry(main)> Message.where.not("direction = ? and body in (?)", "incoming", ['a','b','c'])
  Message Load (0.3ms)  SELECT "messages".* FROM "messages" WHERE (NOT (direction = 'incoming' and body in ('a','b','c')))
=> [#<Message:0x007fee8b29a690 id: 1, direction: "outgoing", body: "a", created_at: Thu, 20 Sep 2018 17:02:35 UTC +00:00, updated_at: Thu, 20 Sep 2018 17:02:35 UTC +00:00>,
 #<Message:0x007fee8b29a3e8 id: 2, direction: "outgoing", body: "b", created_at: Thu, 20 Sep 2018 17:02:35 UTC +00:00, updated_at: Thu, 20 Sep 2018 17:02:35 UTC +00:00>,
 #<Message:0x007fee8b299fb0 id: 3, direction: "outgoing", body: "d", created_at: Thu, 20 Sep 2018 17:02:35 UTC +00:00, updated_at: Thu, 20 Sep 2018 17:02:35 UTC +00:00>,
 #<Message:0x007fee8b299d58 id: 4, direction: "incoming", body: "d", created_at: Thu, 20 Sep 2018 17:02:35 UTC +00:00, updated_at: Thu, 20 Sep 2018 17:02:35 UTC +00:00>]