vol7ron
vol7ron

Reputation: 42179

What's the best way to call an application helper from a controller?

I'd like to format values of a JSON response, to appear the same as how they would in a view.

Consider the object, user = { id: 323 }; a helper method (format_name) has been created to make the value more presentable in the view:

<div>
  <%= format_name(user[:id]) %> 
  <% # appears as: <span class="user" data-user-id="323">John Doe</span> %>
</div>

For known reasons, this isn't available in the controller. The following fails:

class ApplicationHelper

  def format_name
    # ...
  end
end


class UserController < ApplicationController

  def view

    # ...<setup user info>...

    user_formatted = {
      id: user[:id], 
      formatted: format_name(user[:id]) # helper method
    }

    respond_to do |format|
       format.json { render json: user_formatted.to_json }
    end
  end

end

I'm curious how one might use the helper method in the controller.

I've tried:

Upvotes: 2

Views: 5530

Answers (3)

chrismanderson
chrismanderson

Reputation: 4813

(Moving this from a comment to an answer) I would recommend not doing this formatting in your controller but instead using ActiveModelSerializer to handle it. It's part of the rails-api setup and is now ships by default in Rails 5. For your situation, you would do something like:

class UserSerializer < ActiveModel::Serializer
  include ApplicationHelper

  attributes :id, :formatted

  def formatted
    format_name(object)
  end
end

And in your controller, you can just do

def show
  render json: User.find(params[:id)
end

Upvotes: 5

Frost
Frost

Reputation: 11987

You can do this by either including your helper module in the controller, or you can use module_function to declare your helper method as callable directly on the module, sort of like a class method.

Say that your helper function is declared in this helper module:

module ApplicationHelper
  def format_name(user_id)
    # do stuff
  end
  module_function :format_name  # Here's the "magic" line
end

By adding that module_function :format_name line, you can now call your helper function just like ApplicationHelper.format_name(user[:id]) in the controller.

Upvotes: 5

7urkm3n
7urkm3n

Reputation: 6321

###helper    
module MyHelper
  def format_name(user_id)
     #code goes here
  end
end

###html
<div>
  <%= format_name(user[:id]) %> 
</div>

###controller
class SampleController < ApplicationController
  include MyHelper

  def view
    puts format_name(user[:id])
  end
end

Upvotes: 2

Related Questions