← Back to Upcase

is_a? in a view helper

(Matthew Sumner) #1

I’ve got a partial view that I can use to show several types of models. The only difference I have between objects is a subtitle otherwise the partial is unchanged between objects. I’ve gone with:

module TitleHelper
  def title(object)
    if object.is_a? SomethingA
      #show this
    elsif object.is_a? SomethingB
      #show that
      #show default

However, I’ve read that is_a? is something to be avoided. How should I be handling this snippet of view logic?

(Ben Orenstein) #2

One way: define to_partial_path on each object. Have a different partial for each object type and use those to hold the differences.

So your view would look like this:

<%= render @object %>

Each object would define to_partial_path (which Rails uses to find the partial to render in our call above.

For further discussion and examples, check out Ruby Science; specifically the Polymorphic Partials section.

(Matthew Sumner) #3

Thanks @benorenstein, what would be the strategy if you had already used the to_partial_path?

I love the concept of to to_partial_path and it seems like a powerful tool. Our application is showing objects in lots of different ways throughout the application and I wonder if there is a way to have several to_partial_path options? Maybe:

def to_partial_path(style = :default)
  case style
  when default
    # default path
  when :awesome
    # super awesome path
    # raise UnkownStyleError

Can you see any reason this would be a bad idea? Can you even pass the argument through?

(Chad Pytel) #4

That would break the normal api for to_partial_path (which normally takes no argument) and so I would recommend against it. And as you guess, I don’t think you can even pass an argument through.

Instead, you can make a new helper method that builds on top of to_partial_path

module TitleHelper
  def title_partial_path(object)

So if you have an Episode model, it would make it so that the helper would return episodes/episode_title

The helper can be used like this:

render title_partial_path(episode), episode: episode

(Matthew Sumner) #5

Thanks @cpytel. That will work great!