One extension to Rails ActionController::Base#render
method I don’t like is
the new :update parameter. This is used to render inline RJS in an action like:
class CommentsController < ApplicationController
def create
@comment = Comment.new params[:comment]
respond_to do |wants|
if @comment.save
wants.js do
render :update do |page|
page.insert_html :bottom, 'comments', render(:partial => 'comment',
:object => @comment)
page[:errors].replace_html ''
page[:comment_form].reset
end
end
else
wants.js do
render :update do |page|
page[:errors].replace_html @comment.errors.full_messages
end
end
end
end
end
end
That’s a very simple AJAX
comment submission. Instead of creating RJS templates in app/views/comments
I
just rendered the RJS inline in the action. I think this is bad because:
- look at how much longer the action is
- the nesting makes it a pain to read
- in this case the error display will be ugly because I can’t call view methods
such as
#error_messages_for
in a controller so I’m forced to callActiveRecord::Errors#full_messages
.
I think it’s much better to use RJS views instead. Then the above action becomes:
class CommentsController < ApplicationController
def create
@comment = Comment.new params[:comment]
respond_to do |wants|
if @comment.save
wants.js
else
wants.js { render :action => 'new.rjs' }
end
end
end
end
In create.rjs
:
page.insert_html :bottom, 'comments', render(:partial => 'comment',
:object => @comment)
page[:errors].replace_html ''
page[:comment_form].reset
In new.rjs
:
page[:errors].replace_html error_messages_for(:comment)
Then you say but it’s only a couple lines of RJS, why create 2 more files just for that?. My answer would be: do you ever write normal non-AJAX actions like this:
class PostsController < ApplicationController
def show
@post = Post.find params[:id]
html =<<-EOS
<h2>#{@post.title}</h2>
#{@post.body}
EOS
render :text => html, :layout => 'application'
end
end
Of course not.
In my opinion, the :text and :update parameter options in
ActionController#Base
should both be deprecated.