Skip to content

Instantly share code, notes, and snippets.

@shicholas
Last active August 29, 2015 14:00
Show Gist options
  • Save shicholas/cf3caf7a21fabf4e1a2f to your computer and use it in GitHub Desktop.
Save shicholas/cf3caf7a21fabf4e1a2f to your computer and use it in GitHub Desktop.
Replacing Controllers and Routes with Action Objects

I've been intrigued with the idea of action objects seen at the LVRUG podium app and have been thinking how these objects can replace controllers altogether. The more I think about it, I think these classes can replace both controllers and routing if they were namespaced and inherited in a standardized way.

Take the example from the podium app (as of 4/30/2014):

module Topics
  class DisplayTopics
    attr_defaultable :reader_factory, -> { Repositories::Reads::ReadTopics }

    def call(&block)
      yield ResponsiveService::Response.new(:success, '', results)
    end

    private

    def results
      reader_factory.new({}).call
    end
  end
end

This class's name with the Topics namespacing is Topics::DisplayTopics. While that name is descriptive of what the class encompasses, coming from a background of restful resources I would like to see that class named Topics::Index. If it was so, it could be relatively conceivable for a rake task to generate routes based off the namespacing. In this case the route generated would be /topics.

Restful resources and routing

The next thought I had was, what if these action classes could inherit from classes to designate what HTTP verb should correspond to the routing and could create typical restful routes found in rails apps. Classes could then look like:

class Topics::Index < Get
  # return topics
end

class Topics::New < Get
  # Create a topic for a new topic form
end

class Topics::Create < Post
  # Submit a topic to the server
end

class Topics::Update < Patch
  # update a Topic
end

If a class did not use a restful resource (index, new, create, show, update, delete), then the route would be generated per its declaration, i.e. Topics::FeaturedTopics < Get would create a route of topics/featured_topics.

Authentication & Authorization

These two things are normally handled at the controller level in rails and could be handled by deferring to another class with dependency injection, or by using a refinement; it would be cool to write a class like:

class Topics::Create < Post
  include Authorization # refines what needs to be refined for auth.
  # Submit a topic to the server
end

Strong Params

Rails 4 introduced strong parameters, which is a good theoretical concept, but having to write permit with a long list of parameters is tedius. I would like to build something into the classes that inherit from Post, Put, and Delete a way to only permit those parameters referenced in that class. I don't foresee a clean solution to this however and would love some input on it. I figure a good solution would be to raise an exception for unused parameters, but I am uneasy about my current approaches to it.

Ultimate Goal

Ideally these classes could let me do:

rm -rf app/controllers
rm config/routes.rb

and by their mere declaration and subclassing, could accomplish everything controllers and routing currently do in rails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment