简体   繁体   中英

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:

  • view_context.format_name
  • creating a partial (eg, _view.json.erb ) to call the helper and render json
  • setting helper_method :format_name in the ApplicationController

(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

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.

###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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM