pulling complicated logic out of views

5 views
Skip to first unread message

Mark Locklear

unread,
Nov 1, 2013, 11:14:20 AM11/1/13
to ashevi...@googlegroups.com

I have a view that is getting complicated, and I'm wondering I should be doing this different? Picture (or code) is worth a 1000 words, so heres the view...

    <% @orientation_by_date[date].each do |orientation| %>
      <% if current_user %>
        <% if orientation.active? %>
          <li><%= link_to orientation.class_time, new_orientation_registration_path(orientation) %>
              (<%= orientation.current_number_seats %>/<%= orientation.seats %>)</li>
        <% else %>
          <li><%= orientation.class_time %>(Class full)</li>
        <% end %>
        <%= link_to "VIEW", orientation_registrations_path(orientation) %></li>
      <% else %>
        <% if orientation.active? %>
          <li><%= link_to orientation.class_time, new_orientation_registration_path(orientation) %>
              (<%= orientation.current_number_seats %>/<%= orientation.seats %>)</li>
        <% elsif orientation.class_date.before Date.today %>
          <li><%= orientation.class_time %>(Class Closed)</li>
        <% end %>
        <% else %>
          <li><%= orientation.class_time %>(Class full)</li>
        <% end %>
      <% end %>
    <% end %>

What you are looking at is a the front end calendar view of a scheduling application. Based on differnt states, you see different information in each day on the calendar, ie, the number of seats remaining, vs. 'Class Full' vs. something else for Admins. Should I be pulling this logic into my model or controller somehow?



--
J. Mark Locklear
-Philippians 4:13 gives you the muscle, but YOU have to flex it!

-He who works with his hands is a laborer.
-She who works with her hands and her head is a craftswomen.
-Those who work with their hands, their head, and their hearts are artists.

Andy Vanasse

unread,
Nov 1, 2013, 7:43:52 PM11/1/13
to Asheville Ruby Users Group
Hey Mark,

There are lots of ways to skin the cat.  Which is 'right' is as much about personal preferences as anything else.  That said, here are a few ideas that you might want to consider.

  • Use partials for each type of user
    This may or may not be your driving concern but the outermost layer of decision making is based on user type so it may make sense to build a partial for each type of user.  In this case you might have 'active_user_orientation_view' and 'guest_orientation_view'.  Doing that reduces (this section) of your view down to a single if-then-else statement with pretty clear indication of your intent -- registered users see one thing and guests see something else.

  • Wrap-up repeating code into helper methods
    Two of the list items are generated using the exact same code.  Make it DRY!  As an example, I'd probably drop down into the OrientationsHelper (app/helpers/orientations_helper.rb) and add a #orientation_full_item helper like this

    def orientation_full_item(orientation)
      content_tag(:li) do
        "#{orientation.class_time} (Class full)"
      end
    end

    With that helper in place, the two lines rendering the "Class full" message could be reduced to <%= orientation_full_item(orientation) %>.  You could do the same for the list item that provides a link to the registration form.  For consistency, you might do it for all of the list items.  That would give you a view that very clearly declares its intentions.

  • Consider using a Presenter
    Rather than litter your model (business logic) with view-oriented convenience methods, a better choice would be to create a new class that accepts an instance of the class and provides the same convenience methods.  This is what the Presenter pattern is all about.  The advantage of it is that you very clearly organize your code along the lines of it's intention -- biz logic stays together and stays untangled from view logic.  In this case you might provide an
    ActiveUserOrientationPresenter and a GuestOrientationPresenter class, each of which provides a #list_item convenience method capable of rendering out the list item with its appropriate contents.

    The PragProg guys have a title written by Bruce Williams with some great suggestions on how to build robust view code that is probably worth the money and time invested.  One of the available code snippets deals specifically with presenters.  You can read it here.


--
You received this message because you are subscribed to the Google Groups "Asheville Ruby Users Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to asheville-rb...@googlegroups.com.
To post to this group, send email to ashevi...@googlegroups.com.
Visit this group at http://groups.google.com/group/asheville-rb.
For more options, visit https://groups.google.com/groups/opt_out.

Bruce Hauman

unread,
Nov 1, 2013, 7:59:19 PM11/1/13
to ashevi...@googlegroups.com
+1 for Presenters

Mark Locklear

unread,
Nov 1, 2013, 9:15:33 PM11/1/13
to ashevi...@googlegroups.com
Wow! Awesome feedback Andy. I'll read over that link. Did not even consider partials, so thats an easy option if the presenters don't click.
Reply all
Reply to author
Forward
0 new messages