bin/rails g model comment body:text commentable:references{polymorphic}
- which generates migration file
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :body
t.references :commentable, polymorphic: true, index: true
t.timestamps null: false
end
end
end
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
has_many :comments, as: :commentable
- now we can create comment using commentable
2.2.3 :001 > c = Campaign.last
Campaign Load (0.9ms) SELECT "campaigns".* FROM "campaigns" ORDER BY "campaigns"."id" DESC LIMIT 1
+----+--------+--------+------+--------+--------+--------+--------+--------+-------+-------+--------+--------+--------+
| id | name | des... | goal | end... | cre... | upd... | use... | slug | image | aa... | add... | lon... | lat... |
+----+--------+--------+------+--------+--------+--------+--------+--------+-------+-------+--------+--------+--------+
| 8 | Hel... | hello | 30 | 201... | 201... | 201... | | hel... | | fu... | 142... | -12... | 49.... |
+----+--------+--------+------+--------+--------+--------+--------+--------+-------+-------+--------+--------+--------+
1 row in set
2.2.3 :002 > c.comments.create(body: "My first comment")
(0.1ms) BEGIN
SQL (0.5ms) INSERT INTO "comments" ("body", "commentable_id", "commentable_type", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["body", "My first comment"], ["commentable_id", 8], ["commentable_type", "Campaign"], ["created_at", "2016-03-18 21:29:14.711756"], ["updated_at", "2016-03-18 21:29:14.711756"]]
(1.3ms) COMMIT
+----+------------------+----------------+------------------+-------------------------+-------------------------+
| id | body | commentable_id | commentable_type | created_at | updated_at |
+----+------------------+----------------+------------------+-------------------------+-------------------------+
| 1 | My first comment | 8 | Campaign | 2016-03-18 21:29:14 UTC | 2016-03-18 21:29:14 UTC |
+----+------------------+----------------+------------------+-------------------------+-------------------------+
def show
# find by id is going to return nil instead of throwing an error is id not found
# @campaign = Campaign.find_by_id params[:id]
# render :show
@comment = Comment.new
end
<hr>
<%= simple_form_for [@campaign, @comment] do |f| %>
<%= f.input :body %>
<%= f.submit class: "btn btn-primary" %>
<% end %>
class CommentsController < ApplicationController
before_action :authenticate_user
before_action :find_commentable
def create
@comment = Comment.new comment_params
@comment.commentable = @commentable
if @comment.save
redirect_to @commentable, notice:"comment created!"
else
render "#{@commentable.class.to_s.underscore.pluralize}/show"
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
def find_commentable
if params[:campaign_id]
@campaign = @commentable = Campaign.friendly.find params[:campaign_id]
end
end
end
<h2>Comments</h2>
<% @campaign.comments.each do |comment| %>
<div class="well col-md-3">
<p><%= comment.body %></p>
</div>
<% end %>