Regards,
KyleComment Model
class Comment < ActiveRecord::Base
belongs_to :post
before_save :set_username
private
def set_username
self.created_by = current_user
end
end
Application Controller (This is just a Sandbox app so I just put a string in the method)
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_user
def current_user
"FName LName"
end
end
Show View
<p id="notice"><%= notice %></p>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
<div id="show_comments"><%= render 'comments' %></div>
<div id="add_comments">
Add Comment
<%= form_for @post, :url => {:action => 'update', :id => @post.id}, :html => { :'data-type' => 'html', :id => 'create_comment_form' } do |f| %>
<%= f.fields_for :comments, @new_comment do |comment_fields| %>
<%= comment_fields.text_area :content %>
<%end%>
<div class="validation-error"></div>
<%= f.submit %>
<% end %>
</div>
Post Controller
def update
@post = Post.find(params[:id])
respond_to do |format|
if @post.update_attributes(params[:post])
@comments = @post.comments.all
format.html { redirect_to({:action => :show, :id => @post.id}, :notice => 'Post was successfully created.') }
format.xml { render :xml => @post, :status => :created, :location => @post }
else
format.html { render :action => "new" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end
I was originally thinking you could just set it as a default or a before_save in the model. But models don't have access to current_user
. So it's probably best to just set the current user in the controller. It's not as DRY as putting it in the model but it's less hackey and potentially problematic this way.
def update
@post = Post.find(params[:id])
@post.attributes = params[:post]
@post.comments.each do |comment|
comment.created_by = current_user if comment.new_record?
end
respond_to do |format|
if @post.save
@comments = @post.comments.all
format.html { redirect_to({:action => :show, :id => @post.id}, :notice => 'Post was successfully created.') }
format.xml { render :xml => @post, :status => :created, :location => @post }
else
format.html { render :action => "new" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end
Just want to point out that it is possible to access current_user
in the model scope. In this case I don think it is necessary, as the solution from @aNoble should work. So if is possible to set the current_user from the controller, I would prefer that.
In short, we add a method to the User
class
class User < ActiveRecord::Base
cattr_accessor :current_user
def self.current_user
@current_user ||= User.new("dummy-user")
end
...
end
and in your application controllor, we add a before_filter
that sets it. Make sure to call this filter after your authentication is done.
class ApplicationController < ActionController::Base
before_filter { |c| User.current_user = current_user }
end
And, then inside your Comment
-model you could just do something like
class Comment
before_create :set_user
def set_user
created_by = User.current_user unless created_by
end
end
(so I only set the created_by
if it was not yet set, and only upon creation of a new comment).
精彩评论