Fellow Stranger
Fellow Stranger

Reputation: 34013

Get all articles that a certain user hasn't commented on

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

Answers (4)

Mani dhayal
Mani dhayal

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

Alex River
Alex River

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

Richard Peck
Richard Peck

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

Sajjad Murtaza
Sajjad Murtaza

Reputation: 1504

Try this one.

Article.joins(:comments).group('article.id').having('count(comments.id) =0')

Upvotes: 0

Related Questions