RailsCasts Pro episodes are now free!

Learn more or hide this

Tyler Collier's Profile

GitHub User: tylercollier

Comments by Tyler Collier


Is there an elegant way to deal with optionally-passed locals?

For example say I call

<%= render 'posts/post', post: post, :size => :panel %>

How can I access that size value in the presenter?

One way is to pass the value into the presenter. For example, from the partial, I might write

<%= post_presenter.some_method(size) %>

But since size is an optional value passed to the partial, it might not exist, and thus would raise an exception when trying to call some_method. You could check if the local variable exists like this:

<% if defined?(size) %>
<% else %>
  # Don't call presenter method at all, or do other logic.
<% end %>

However, this is ugly, and defeats the point of the presenter! This is the code that we're trying to avoid in the first place.



I like it. I'm not sure if I agree with Jeremy Seitz, as I did something similar to Austin Schneider.

# presenters/post_presenter.rb
# Note the variable passed in to `present` is also the argument given to the block; this is intentional, see my explanation below.
<% present post do |post| %>
  <div class="<%= post.css_class %>">
    <div class="caption"><%= post.caption %></div>
    <div class="image">
      <%= image_tag(post.image_url) %>
    <div class="description">
      <%= post.description %>
    <div class="rating">
      <%= post.rating %>
<% end %>
class BasePresenter

  def method_missing(*args, &block)
    @object.send(*args, &block)

In my view code, note that you can't tell the difference between post (as PostPresenter) and post (my active record model). I think the ambiguity is fine, or good actually; it's easy to read. To be able to do that, I overrode method_missing to point to the model. That way I don't have to use delegate. But this makes it a little easier to deal with when shifting code around via partials and not having to rename passed locals.