When to split up a controller

Hi all,

Hoping you can help,

I’ve been using a lot of cancan, and in particular the load and authorize functionality. Unfortunately I feel that this has a side effect when dealing with nested routes in particular, of either hiding away implicit conditionals in the controller action, or forcing conditionals through case statements when you want to return something different than just @resource.posts for example.

After reading Rails anti-patterns, and dealing with this for a while, I feel like I should perhaps be reaching for a new controller when I declare a new nested route with the same resource particularly if its a choice between a conditional, or just a small controller with one action. However someone has suggested I should just use a case statement instead, which I feel is not the right choice.

What are people’s opinions here? How have you approached this problem?

Hi @Tom_Ridge, I don’t quite understand the question, can you add a code sample?

hey @pedromoreira sure, I’ll use a bit of a contrived example so bear with me:

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    case 
     when @company
        @company.posts
     when @user
        @user.posts
     else
        Post.all  
    end
  end
end


# config/routes.rb

resources :companies do
   resources :posts 
end

resources :posts 

resources :users do
   resources :posts
end

I would put in the possible conditional logic in the views, but hopefully you get the idea.

I feel pretty strongly that when nesting resources, whilst maybe not straight away, I should be looking to split these up into separate controllers. Quite often this conditional logic is hidden away via cancan load_and_authorize which makes me especially dubious as Ive just hidden the conditional logic away into a series of hard to understand statements at the top of my controller, rather than made any real change.

However I have met some advocates for using a case statement.

Right, so I guess you are using nesting to figure out what entity you have from the params and this is not something you care about in URL design?

If you don’t care about it in URL, I’d break the nesting and figure out if there is an object that knows which set of posts to return given a set of params is something waiting to emerge.

When faced with a case statement, I do try and bring out an object that can answer the question I am placing. In this case, it seems to be “Which set of posts do I return for X”? So maybe that is a query object waiting in the wings, prepared for you to tell it, “Hey, get me the posts for X”.

I might have missed the point of your question, though, so let me known your thoughts on this.

1 Like