ruby-on-rails - validates - ruby rails介绍




如何用ActiveRecord/Rails表达NOT IN查询? (10)

上面的大部分答案都可以满足你,但如果你正在做更多这样的谓词和复杂组合,请检查Squeel 。 你将能够做到这样的事情:

Topic.where{{forum_id.not_in => @forums.map(&:id)}}
Topic.where{forum_id.not_in @forums.map(&:id)} 
Topic.where{forum_id << @forums.map(&:id)}

只是为了更新这个,因为看起来很多人都这样认为,如果您使用Rails 4,请查看TrungLê`和VinniVidiVicci的答案。

Topic.where.not(forum_id:@forums.map(&:id))

Topic.where(published:true).where.not(forum_id:@forums.map(&:id))

我希望有一个简单的解决方案,不涉及find_by_sql ,如果不是,那么我想这将不得不工作。

我发现这篇文章引用了这个:

Topic.find(:all, :conditions => { :forum_id => @forums.map(&:id) })

这是一样的

SELECT * FROM topics WHERE forum_id IN (<@forum ids>)

我想知道是否有办法不这样做,如:

SELECT * FROM topics WHERE forum_id NOT IN (<@forum ids>)

仅供参考,在Rails 4中,您可以使用not语法:

Article.where.not(title: ['Rails 3', 'Rails 5'])

你可以尝试如下所示:

Topic.find(:all, :conditions => ['forum_id not in (?)', @forums.map(&:id)])

您可能需要执行@forums.map(&:id).join(',') 。 我不记得Rails是否会将参数列入CSV列表中,如果它是可枚举的。

你也可以这样做:

# in topic.rb
named_scope :not_in_forums, lambda { |forums| { :conditions => ['forum_id not in (?)', forums.select(&:id).join(',')] }

# in your controller 
Topic.not_in_forums(@forums)

你可能想看看Ernie Miller的meta_where插件 。 你的SQL语句:

SELECT * FROM topics WHERE forum_id NOT IN (<@forum ids>)

...可以这样表达:

Topic.where(:forum_id.nin => @forum_ids)

Railscasts的Ryan Bates创建了一个很好的视频解释MetaWhere

不知道这是你在找什么,但在我看来,它肯定比嵌入式SQL查询更好看。


原来的文章特别提到使用数字ID,但我来到这里寻找使用字符串数组做NOT IN的语法。

ActiveRecord也会为你处理:

Thing.where(['state NOT IN (?)', %w{state1 state2}])

如果@forums为空,则接受的解决方案将失败。 为了解决这个问题,我必须这样做

Topic.find(:all, :conditions => ['forum_id not in (?)', (@forums.empty? ? '' : @forums.map(&:id))])

或者,如果使用Rails 3+:

Topic.where( 'forum_id not in (?)', (@forums.empty? ? '' : @forums.map(&:id)) ).all

我正在使用这个:

Topic.where('id NOT IN (?)',actions)

actions是一个数组: [1,2,3,4,5]

编辑:

对于Rails 4表示法:

Article.where.not(title: ['Rails 3', 'Rails 5']) 


这些论坛ID可以用实用的方式解决吗? 例如,你能否以某种方式找到这些论坛 - 如果是这样的话,你应该这样做

Topic.all(:joins => "left join forums on (forums.id = topics.forum_id and some_condition)", :conditions => "forums.id is null")

哪一种比不进行SQL更有效率?


这是一个更复杂的“不在”查询,在使用squeel的rails 4中使用子查询。 当然与等效的sql相比非常慢,但是,嘿,它的工作原理。

    scope :translations_not_in_english, ->(calmapp_version_id, language_iso_code){
      join_to_cavs_tls_arr(calmapp_version_id).
      joins_to_tl_arr.
      where{ tl1.iso_code == 'en' }.
      where{ cavtl1.calmapp_version_id == my{calmapp_version_id}}.
      where{ dot_key_code << (Translation.
        join_to_cavs_tls_arr(calmapp_version_id).
        joins_to_tl_arr.    
        where{ tl1.iso_code == my{language_iso_code} }.
        select{ "dot_key_code" }.all)}
    }

范围中的前2个方法是声明别名cavtl1和tl1的其他范围。 <<是squeel中的not in运算符。

希望这可以帮助某人。







activerecord