Reputation: 34013
I have three models: Article, Comment, User.
A user can comment on an article.
Here's how to get all articles where there's no comment at all, but I only want those that a certain user has not commented on yet:
Article.includes(:comments).where(:comments => { :id => nil })
Update
class Article
has_many :comments
end
class Comment
belongs_to :article
belongs_to :user
end
class User
has_many : comments
end
Upvotes: 1
Views: 442
Reputation: 270
Add this method to article class
class Article < ActiveRecord::Base
def self.with_no_comments_by(user)
includes(:comments).
references(:comments).
where.not(comments: { user_id: user.id })
end
end
Upvotes: 0
Reputation: 25
I just had to face the same issue, but the answers provided don’t seem to be working:
@articles = Article.joins(:comments).where.not(comments: {user_id: @user.id})
or the various different variants, will also return articles commented by the user if they where commented also by other users. E.g. Article1: commentA by user1, commentB by user2
I’ve found this truly inelegant solution:
#app/models/article.rb
class Article < ActiveRecord::Base
has_many :comments
has_many :users, through: :comments #create a many-to-many relations
end
and
@articles = Article.joins(:comments).reject {|f| f.users.where(id: @user.id).present? }
Ugly and very expensive in terms of performance (many SQL queries). For details on reject check the details HERE
Hope somebody finds a more elegant and efficient way
Upvotes: 1
Reputation: 76774
#app/models/article.rb
class Article < ActiveRecord::Base
scope :no_user_comments, ->(id) { joins(:comments).where('comments.user_id NOT IN (?)', id) }
end
You can then pass:
@articles = Article.no_user_comments @user.id
or
@articles = Article.no_user_comments [@user.id, "15", "25"]
Upvotes: 1
Reputation: 1504
Try this one.
Article.joins(:comments).group('article.id').having('count(comments.id) =0')
Upvotes: 0