简体   繁体   中英

Rails 5 in applicationHelper an helper is visible, another not

I'm learning rails. I'm build a simple test application, with a simple authentication scheme. I'm using a user.role field to group the users. In my Application Helper i have:

module ApplicationHelper
def current_user
  if session[:user_id]
    @current_user ||= User.find(session[:user_id])
  else
    @current_user = nil
  end
end

def user_identity
  current_user.role if current_user
end
end

Now, in my app, i can use current_user in all controllers as expected, but instead user_identity is not visible.

why?

The application_helper is used mainly to access methods in views - I don't believe it's available in a controller.

The reason your 'current_user' method appears to work is that I'm assuming you're using Devise - when you call 'current_user' it is using the Engine's method rather than your own.

To solve this, write out a new module:

module MyHelper
  def current_user
    if session[:user_id]
      @current_user ||= User.find(session[:user_id])
    else
      @current_user = nil
    end
  end

  def user_identity
    current_user.role if current_user
  end
end

And in the controller you're using:

class MyController < ApplicationController
  include MyHelper

  bla bla bla...
end

Any methods defined in MyHelper will now be available in MyController, as we've included the module in the controller

Helper modules are mixed into the view context (the implicit self in your views) - not controllers.

So you can call it from the controller with:

class ThingsController < ApplicationController
  # ...
  def index
    view_context.user_identity
  end
end

Or you can include the helper with the helper method:

class ThingsController < ApplicationController
  helper :my_helper
  def index
    user_identity
  end
end

But if you're writing a set of authentication methods I wouldn't use a helper in the first place. Helpers are supposed to be aids for the view.

Instead I would create a concern (also a module) and include it in ApplicationController:

# app/controllers/concerns/authenticable.rb
module Authenticable
  extend ActiveSupport::Concern
  def current_user
    @current_user ||= session[:user_id] ? User.find(session[:user_id]) : nil
  end 

  def user_identity
    current_user.try(:role)
  end
end

class ApplicationController < ActionController::Base
  include Authenticable
end

Since the view can access any of the controllers methods this adds the methods to both contexts.

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