ruby-on-railsrubyhaml

Rails helper in view - How to have the result of a helper rendered?


In a view, I have a very simple condition to apply on an number to decide to wrap it by a span with either the .negative or .positive class (making it red or green).

The below code is working... But is to be reused a lot.

.col-3
  - if item.amount.positive?
    %span.positive
      = item.amount
  - else
    %span.negative
      = item.amount

So in order to be DRY, I want to make it a "helper" in application_helper.rb. I found this How to use Haml in your helpers and wrote a helper as follows:

def amountColor(x)
  puts "============================================"
  - if x.positive?
      puts "POSITIVE"
      render_haml <<-HAML, amount: x
        %span.positive= amount
      HAML
    else
      puts "NEGATIVE"
      render_haml <<-HAML, amount: x
        %span.negative= amount
      HAML
    end
  puts "============================================"
end

And I attempt to call it like this:

.col-3
  -amountColor(item.amount)
  Nothing displays just above this line.

In the server's console, I get:

  Rendering pages/home.html.haml within layouts/application
============================================
NEGATIVE
<span class='negative'>-100</span>
============================================
  Rendered pages/home.html.haml within layouts/application (Duration: 1.8ms | Allocations: 1856)
  Rendered layout layouts/application.html.haml (Duration: 2.6ms | Allocations: 2379)
Completed 200 OK in 27ms (Views: 3.5ms | ActiveRecord: 2.1ms | Allocations: 13435)

Which makes me think the helper is called and does its job quite right... But the span is not rendered.

Now if I try (= instead of -):

.col-3
  = amountColor(item.amount)

It renders the span as text...

enter image description here


Solution

  • In order to actually render the HTML, you will need to use html_safe

    = amountColor(item.amount).html_safe
    

    You could also just inline it and remove the need for the helper altogether:

    - klass = item.amount.positive ? 'positive' : 'negative'
    %span{class: klass}= item.amount