Reputation: 2293
Within my rails app, I currently have comments setup to work with my posts model, which is functioning properly. How do I add comments to my books model?
Here is what I have so far:
Here is what I have in my schema for the comments:
create_table "comments", force: true do |t|
t.text "body"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.integer "post_id"
t.integer "book_id"
end
In my user model:
class User < ActiveRecord::Base
has_many :comments
acts_as_voter
end
In my post model:
class Post < ActiveRecord::Base
has_many :comments
end
In my book model:
class Book < ActiveRecord::Base
has_many :comments
end
In my comment model:
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :book
belongs_to :user
acts_as_votable
end
In my comments controller:
class CommentsController < ApplicationController
def create
post.comments.create(new_comment_params) do |comment|
comment.user = current_user
end
respond_to do |format|
format.html {redirect_to post_path(post)}
end
end
def upvote
@post = Post.find(params[:post_id])
@comment = @post.comments.find(params[:id])
@comment.liked_by current_user
respond_to do |format|
format.html {redirect_to @post}
end
end
private
def new_comment_params
params.require(:comment).permit(:body)
end
def post
@post = Post.find(params[:post_id])
end
end
In my routes file:
resources :posts do
resources :comments do
member do
put "like", to: "comments#upvote"
end
end
end
In my view:
<% @post.comments.each do |comment| %>
<%= comment.body %>
<% if user_signed_in? && (current_user != comment.user) && !(current_user.voted_for? comment) %>
<%= link_to “up vote”, like_post_comment_path(@post, comment), method: :put %>
<%= comment.votes.size %>
<% else %>
<%= comment.votes.size %></a>
<% end %>
<% end %>
<br />
<%= form_for([@post, @post.comments.build]) do |f| %>
<p><%= f.text_area :body, :cols => "80", :rows => "10" %></p>
<p><%= f.submit “comment” %></p>
<% end %>
What do I add to my comments controller to get comments working on both posts and books? What do I add to my routes file?
Thanks in advance for any help.
Upvotes: 2
Views: 1209
Reputation: 23939
You don't want to specify each type of object that can hold Comment
objects. That creates a headache of if-elsif-else
blocks all over the place. Instead, you want things to be Commentable
, and they all will have .comments
on them.
This is called a polymorphic association in Active Record. So you would have your models something like:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
class Post < ActiveRecord::Base
has_many :comments, as: :commentable
end
class Book < ActiveRecord::Base
has_many :comments, as: :commentable
end
And modify your database accordingly, it's all in the linked article. Now when you build a Comment
object for a form, it will have pre-populated a commentable_id
and commentable_type
, which you can toss in hidden fields. Now it doesn't matter what the Comment
is associated with, you always treat it the same.
I'd leave User
as a separate association, since it's not really the same idea.
Upvotes: 10