Alicia Vila
Alicia Vila

Reputation: 3

Ruby on rails - How to add an item to a has_many reference?

I am new on RoR and I have to implement a User - Submissions - Comments app. The thing is, I would like the users can like the submissions and the comments, but just once for each submission/comment.

For that, my user model is (the class is called guser):

class Guser < ActiveRecord::Base

  has_many :liked_submissions, :class_name => "Submission", :foreign_key => "submission_id"

In the view, I call a function from the Submission Controller called like:

def like     
     @submission = Submission.find(params[:submission_id])
     @submission.nlikes = @submission.nlikes + 1
     @submission.save
     current_guser.liked_submissions << @submission     
     current_guser.save     
     redirect_to submissions_path
   end

The thing is I get this error: can't write unknown attribute submission_id

and I don't understand why because I searched everywhere how to add an object to a has_many reference and all the posts say I must use the << operator. But it doesn't work. Can someone help me?

Thank you very much.

EDIT: I followed Anthalee advices and now I have another problem. I did exactly the new Likes model first just using submissions and later I transformed it to polimorphic as Anthalee recommended me. Now the thing is I want to show the like button only if the user did not already liked the submission or comment. When there was only the submission, I could use the map:

<%if current_guser and not current_guser.likes.map(&:submission_id).include? submission.id %>
+        <%= link_to(image_tag("https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Green_equilateral_triangle_point_up.svg/1182px-Green_equilateral_triangle_point_up.svg.png", :width => 8, :height => 8), { :controller => "likes", :submission_id => submission.id,:action => "create"}, method: :post) %>
       <%end%>

But now I don't know how to check the type of the reference (submission or comment) and the id in the current user likes.

How can I do it?

Upvotes: 0

Views: 355

Answers (1)

Anchalee
Anchalee

Reputation: 666

You need a separate Likes join table between Users and Submissions. Then it's as simple as just hitting the likes_controller #create action with user_id and submission_id.

  def create
    @like = Like.create(
      user_id: current_user.id,
      submission_id: params[:submission_id]
    )

    render #whatever
  end

  def destroy
    @like = current_user.likes.find_by_submission_id(params[:submission_id])
    @like.destroy!
    render :json => @like
  end

  private 
  def like_params
    params.require(:like).permit(:submission_id)
  end

in User.rb:

has_many :likes, dependent: :destroy

in Submission.rb:

has_many :likes
has_many :likers, through: :likes, source: :user

in Like.rb:

belongs_to :user
belongs_to :submission

To allow both submissions and comments to get likes, just make your Likes association polymorphic.

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

Upvotes: 2

Related Questions