Reputation: 1123
So, I'd like users to be able to comment. At the present moment anyone can comment just by typing in a arbitrary name in the name field.
But I'd like to associate a comment with a user. So there will no longer be a need for a name field in the comments form as it will be the users name.
How can this be done?
I've followed Ryan Bates railscast but he never associates comments with users.
comments_controller.rb
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
def index
@comments = Comment.where("song_id IS NOT ?", nil)
end
def show
end
# GET /comments/new
def new
end
# GET /comments/1/edit
def edit
end
# POST /comments
# POST /comments.json
def create
@comment = Comment.new(comment_params)
respond_to do |format|
if @comment.save
format.html { redirect_to song_url(@comment.song_id), notice: 'Comment was successfully created.' }
format.json { render action: 'show', status: :created, location: @comment}
else
format.html { render action: 'new' }
format.json { render json: @comment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /comments/1
# PATCH/PUT /comments/1.json
def update
respond_to do |format|
if @comment.update(comment_params)
format.html { redirect_to song_url(@comment.song_id), notice: 'Comment was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
@comment.destroy
redirect_to song_url(@comment.song_id)
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
@comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:song_id, :author_name, :site_url, :content, :user_id)
end
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :songs
has_many :comments
acts_as_voter
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :song
end
comments#form.html.erb
<%= form_for @comment do |f| %>
<% if @comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% @comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div id="comment_form">
<div class="field">
<%= f.hidden_field :song_id %>
<p>
<%= f.text_field :author_name, placeholder: "Name" %>
</p>
<p>
<%= f.text_area :content, :rows => '12', :cols => 35, placeholder: "Leave a comment..." %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
<br /><br />
</div></div>
Upvotes: 0
Views: 287
Reputation: 878
Your Comment
table should have a column named user_id
if it does not already. Then you can assign the user_id
two different ways. These assume you have a current_user
method. If you do not, then you will have to fill in the user_id from whatever session store or method you are using.
You could create a hidden_field in your form to assign it.
<%= f.hidden_field :user_id, value: current_user.id %>
but as noted by @rmagnum2002 this could be a security concern due to a user could edit this.
You could assign it during the create action:
def create
@comment = Comment.new(comment_params)
@comment.user_id = current_user.id
respond_to do |format|
if @comment.save
format.html { redirect_to song_url(@comment.song_id), notice: 'Comment was successfully created.' }
format.json { render action: 'show', status: :created, location: @comment}
else
format.html { render action: 'new' }
format.json { render json: @comment.errors, status: :unprocessable_entity }
end
end
end
Assigning this in the controller create action is probably best.
Upvotes: 1