Now that I’ve refactored many of the standard REST methods in NewsController
, I need to work on the non-standard ones. There are two which really bother me, #add_comment
and #destroy_comment
.
If your controllers have actions that include the name of a different model, there is a good chance that a extract class needs to happen. In this case, I’ll start to extract those methods to a new CommentsController
.
Before
1 2 3 4 5 6 7 8 9 10 11 |
class NewsController < ApplicationController def add_comment @comment = Comment.new(params[:comment]) @comment.author = User.current if @news.comments < 'show', :id => @news else show render :action => 'show' end end end |
After
1 2 3 |
class NewsController < ApplicationController # No more add_comment end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class CommentsController :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed } def create @comment = Comment.new(params[:comment]) @comment.author = User.current if @news.comments < 'news', :action => 'show', :id => @news end private # ApplicationController's find_model_object sets it based on the controller # name so it needs to be overriden and set to @news instead def find_model_object super @news = @object @comment = nil @news end end |
When extracting CommentsController
, I also renamed #add_comment
to #create
. It’s a more descriptive name and will make it easier to setup CommentsController
as a REST resource right away. I also had to add a few before_filter
s and utility methods in order for CommentsController
to be fully extracted from NewsController
.
I also had to change how the #create
method handles unsuccessful comments. It’s not an ideal change, but Redmine’s News pages are embedding the commenting forms directly so it would take some major view refactoring before I can get the user experience (UX) right. For now, I’m going to stay focused on the controllers. That’s where I can make the best improvements.