-
Notifications
You must be signed in to change notification settings - Fork 333
Managing Complexity with Presenters
When creating APIs, you should strive manage complexity by using plain old ruby objects and presenters. RABL is a view and like all views, one of the first principles of web development is to keep complex logic out of views. Keep complex logic in a well-organized object that is well-testable.
From David's excellent post, we can see how to simplify complex RABL templates. Take this view as an example:
# post_controller.rb
def show
@post = Post.find(params[:id])
end
# show.rabl
object @post
attributes :title, :body
child :author do
# root_object is a hack for accessing @post
attribute :name => :author_name unless root_object.author == current_user
end
node :publication_date do |post|
if post.status == 'published'
post.published_date
end
end
Simply organize the logic needed in the view within a presenter using Draper and/or plain ruby objects:
# post_presenter.rb
class PostPresenter < Draper::Base
decorates :post
attr_reader :current_user
def initialize(post, current_user)
super(post)
@current_user = current_user
end
def author_name
author.name unless author == @current_user
end
def publication_date
publication_date if status == 'published'
end
end
# post_controller.rb
def show
@post = PostPresenter.new(Post.find(params[:id]), current_user)
end
# show.rabl
object @post
attributes :title, :body, :author_name, :publication_date
Notice that now the logic and complexity is stored in a presenter object and the RABL template is kept clean of complex logic. Keeping complex logic out of views is an important principle in creating maintainable and well-tested applications.
Great articles to read:
I cover most of the above with Testing in isolation, example in RABL on my blog. After writing that, I recently read Objects on Rails and found that Avdi Grimm covers much of the same but explains it better in book format.