Skip to content

Instantly share code, notes, and snippets.

@jennli
Last active March 18, 2016 21:49
Show Gist options
  • Save jennli/d201ea52fe52a92d2396 to your computer and use it in GitHub Desktop.
Save jennli/d201ea52fe52a92d2396 to your computer and use it in GitHub Desktop.
  • generate commentable
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
  • and the comment model:
class Comment < ActiveRecord::Base
  belongs_to :commentable, polymorphic: true
end
  • campaign model:
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 |
+----+------------------+----------------+------------------+-------------------------+-------------------------+

controller

  • campaign show action:
  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
  • show view
<hr>

<%= simple_form_for [@campaign, @comment] do |f| %>
<%= f.input :body %>
<%= f.submit class: "btn btn-primary" %>
<% end %>
  • comments controller
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
  • view
<h2>Comments</h2>
<% @campaign.comments.each do |comment| %>
<div class="well col-md-3">
  <p><%= comment.body %></p>
</div>
<% end %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment