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
.
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
.
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
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.
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.