Ben
Ben

Reputation: 712

What is the best way to factorise this code in rails

I would like to factorise this code (if/else).

In a first way, I do something like this :

  <% @pois.each_with_index do |poi, i| %>
        <div class="card-item">
          <% if poi.poitable.sleep_images.blank? %>
            <div class="card-sleep-thumb" style="background-image: url(<%= cl_image_path("comingsoon.jpg", :width=>600, :crop=>"scale") %>);">
          <% else %>
            <div class="card-sleep-thumb" style="background-image: url(<%= cl_image_path(poi.poitable.sleep_images.first.image, :width=>600, :crop=>"scale") %>);">
          <% end %>

In second way I try another think like this :

<div class="card-sleep-thumb" style="background-image: url(<%= if poi.poitable.sleep_images.blank? ? cl_image_path("comingsoon.jpg", :width=>600, :crop=>"scale" : cl_image_path(poi.poitable.sleep_images.first.image, :width=>600, :crop=>"scale") %>);" %>

But, maybe, there is a better way, with a method in my model ?

How can you do the same thing ?

Upvotes: 0

Views: 117

Answers (2)

user229044
user229044

Reputation: 239402

You can use the || operator, which returns the first "truthy" operand, instead of the if/else you're currently using:

cl_image_path(poi.poitable.sleep_images.first&.image || "comingsoon.jpg")

This argument to cl_image_path will either be the image, if present, or "comingsoon.jpg" otherwise.

A first pass of refactoring you could would look like this:

<% @pois.each do |poi| %>
  <div class="card-item">
    <div class="card-sleep-thumb" style="background-image: url(<%= cl_image_path(poi.poitable.sleep_images.first.image || "coming_soon.jpg"), :width=>600, :crop=>"scale") %>);">
    </div>
   </div>
 <% end %>

However, you can clean this up a lot by dropping each and using collection rendering.

Your existing view would look like this:

<%= render @pois %>

and you would make a new partial containing the HTML representation of a given "Poi". I don't know what the class name is, but if it is Poi, the partial should be placed in app/views/pois/_poi.html.erb, and it would contain the following:

<div class="card-item">
  <div class="card-sleep-thumb" style="background-image: url(<%= cl_image_path(poi.poitable.sleep_images.first.image || "coming_soon.jpg"), :width=>600, :crop=>"scale") %>);">
  </div>
</div>

Upvotes: 0

Tamer Shlash
Tamer Shlash

Reputation: 9523

User a Helper method

class SomeModelHelper
  def some_method_name(poi)
    if poi.poitable.sleep_images.blank?
      cl_image_path("comingsoon.jpg", :width=>600, :crop=>"scale")
    else
      cl_image_path(poi.poitable.sleep_images.first.image, :width=>600, :crop=>"scale")
    end
  end
end


// in the view

<div class="card-sleep-thumb" style="background-image: url(<%= some_method_name(poi).html_safe %>);" %>

Of course, you should use the helper associated with the poi class (e.g PoiHelper if the class is called Poi) and have a more expressive name for the helper method.

Upvotes: 2

Related Questions