Tob*_*ner 198 ruby-on-rails rails-activerecord
只是为了更新这个,因为似乎有很多人来到这里,如果你使用Rails 4,请查看TrungLê`和VinniVidiVicci的答案.
Topic.where.not(forum_id:@forums.map(&:id))
Topic.where(published:true).where.not(forum_id:@forums.map(&:id))
Run Code Online (Sandbox Code Playgroud)
我希望有一个简单的解决方案不涉及find_by_sql,如果不是,那么我想这将必须工作.
我发现这篇文章引用了这个:
Topic.find(:all, :conditions => { :forum_id => @forums.map(&:id) })
Run Code Online (Sandbox Code Playgroud)
这是一样的
SELECT * FROM topics WHERE forum_id IN (<@forum ids>)
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法NOT IN解决这个问题,例如:
SELECT * FROM topics WHERE forum_id NOT IN (<@forum ids>)
Run Code Online (Sandbox Code Playgroud)
Jos*_*tro 295
我正在使用这个:
Topic.where('id NOT IN (?)', Array.wrap(actions))
Run Code Online (Sandbox Code Playgroud)
actions数组在哪里:[1,2,3,4,5]
编辑:
对于Rails 4表示法:
Article.where.not(title: ['Rails 3', 'Rails 5'])
Run Code Online (Sandbox Code Playgroud)
Tru*_* Lê 151
仅供参考,在Rails 4中,您可以使用not语法:
Article.where.not(title: ['Rails 3', 'Rails 5'])
Run Code Online (Sandbox Code Playgroud)
jon*_*nii 50
您可以尝试以下方式:
Topic.find(:all, :conditions => ['forum_id not in (?)', @forums.map(&:id)])
Run Code Online (Sandbox Code Playgroud)
你可能需要这样做@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)
Run Code Online (Sandbox Code Playgroud)
Ped*_*olo 50
使用Arel:
topics=Topic.arel_table
Topic.where(topics[:forum_id].not_in(@forum_ids))
Run Code Online (Sandbox Code Playgroud)
或者,如果愿意:
topics=Topic.arel_table
Topic.where(topics[:forum_id].in(@forum_ids).not)
Run Code Online (Sandbox Code Playgroud)
并且因为导轨4上:
topics=Topic.arel_table
Topic.where.not(topics[:forum_id].in(@forum_ids))
Run Code Online (Sandbox Code Playgroud)
请注意,最终你不希望forum_ids成为id列表,而是一个子查询,如果是这样,那么在获取主题之前你应该做这样的事情:
@forum_ids = Forum.where(/*whatever conditions are desirable*/).select(:id)
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在一个查询中获得所有内容:类似于:
select * from topic
where forum_id in (select id
from forum
where /*whatever conditions are desirable*/)
Run Code Online (Sandbox Code Playgroud)
还要注意,最终你不想这样做,而是一个连接 - 可能更有效.
Vin*_*ret 19
要扩展@TrungLê的答案,在Rails 4中,您可以执行以下操作:
Topic.where.not(forum_id:@forums.map(&:id))
Run Code Online (Sandbox Code Playgroud)
你可以更进一步.如果您需要先过滤已发布的主题,然后过滤掉您不想要的ID,则可以执行以下操作:
Topic.where(published:true).where.not(forum_id:@forums.map(&:id))
Run Code Online (Sandbox Code Playgroud)
Rails 4让它变得如此简单!
Fil*_*sti 12
如果@forums为空,则接受的解决方案失败.要解决这个问题,我必须这样做
Topic.find(:all, :conditions => ['forum_id not in (?)', (@forums.empty? ? '' : @forums.map(&:id))])
Run Code Online (Sandbox Code Playgroud)
或者,如果使用Rails 3+:
Topic.where( 'forum_id not in (?)', (@forums.empty? ? '' : @forums.map(&:id)) ).all
Run Code Online (Sandbox Code Playgroud)