Question

Say I have three models:

Post
 has_many :comment
 has_many :user, through post_user

Comment
 belongs_to Post

User
 has_many :post, through post_user

A logged in user can create/edit ANY post or comment.

Whenever a user create/edits a post or a comment, I want to add the current_user to the post e.g. @post.users << current_user.

How can I ensure this logic without having to replicate it in each controller action? I don't want to use after_save since that would require access to the current_user in the model which won't always be true.

Was it helpful?

Solution

It looks like your associations aren't set up correctly:

Try:

 # Post model associations
 has_many :comments
 has_many :post_users
 has_many :users, through: :post_users

 # Comment model associations
 belongs_to :post
 belongs_to :user    

 # User model associations
 has_many :post_users 
 has_many :posts, through: :post_users   
 has_many :comments

 # PostUser model associations
  belongs_to :user
  belongs_to :post,

Now in your Post controller you can do:

def new
  @post = Post.new
end

def create
  @post = Post.new(params[:post])
  if @post.save
    current_user.posts << @post
    redirect_to :show
  else
    render :new
  end
end

def edit
  @post = Post.find(params[:id])   
end

def update
  @post = Post.find(params[:id])

  if @post.update_attributes(params[:post])
   current_user.posts << @post unless current_user.posts.include(@post)
   redirect_to :show
  else
    render :new
  end
end

Give that a try. You should be able to implement something similar in your Comments controller to get what you need.

UPDATE:

To DRY things up a bit, why not define a method on the Post model (and something similar in the comment model) to handle creating the user association?

def add_user(user)
  self.users << user unless users.include(user)
end

then you can call that each time in the controllers wherever needed:

@post.add_user(current_user)

to replace this:

current_user.posts << @post unless current_user.posts.include(@post)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top