【问题标题】:Helper not defining methods助手未定义方法
【发布时间】:2014-03-28 04:52:05
【问题描述】:

Ruby on Rails 3.2

我的 sessions_controller.rb 会检查 'signed_in_person' 以绕过登录(如果他们已经有记录的会话)。

我的 'signed_in_person' 是在 session_helper.rb 中定义的,但我得到一个错误:

Started POST "/sessions" for 50.241.102.227 at 2014-02-25 10:12:33 -0800
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fFo4EM1MOHNO1Thic6qA/uapGj8pbiNaepKYF5Ge0Tw=", "session"=>{"email"=>"dduck@blah.com", "password"=>"[FILTERED]"}, "com
mit"=>"Sign in"}
Person Load (0.1ms)  SELECT `persons`.* FROM `persons` WHERE `persons`.`email` = 'dduck@blah.com' LIMIT 1
Completed 500 Internal Server Error in 66ms

NoMethodError (undefined method `sign_in_person' for #<SessionsController:0x00000004f7ace8>):
app/controllers/sessions_controller.rb:11:in `create'

从控制台检查时,Person 位于数据库表中。 我的会话控制器:

def create
    if params[:session][:email].include? 'blah.com'
        person = Person.find_by_email(params[:session][:email].downcase)
        if person && person.authenticate(params[:session][:password])
            sign_in_person person
            redirect_back_or person
        else
            flash.now[:error] = 'Invalid email/password combination'
            render 'new'
        end
    else
        ...
    end
end

我的 session_helper:

module SessionsHelper

# For Persons

def sign_in_person(person)
    cookies[:remember_token] = person.remember_token
    self.current_person = person
end

def signed_in_person?
    !current_person.nil?
end
    ...

关于为什么我的 session_helper 没有帮助的任何想法?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3


    【解决方案1】:

    Helper 方法可从视图获得,而不是从控制器获得。

    要从 Controller 中使用它们,(取自 here),您可以:

    1. 在控制器中包含辅助模块
    2. 将助手定义为控制器方法,并通过helper_method :method_name将其标记为助手。

    在您的情况下,由于您将使用来自SessionsHelper 的几种方法,我认为最好包括这样的助手:

    class SessionsController < ApplicationController
      include SessionsHelper
    
    
      ...
    end
    

    【讨论】:

    • 这并没有改变错误,:(如果我将'include SessionsHelper'添加到我的persons_controller,错误就消失了。可以吗?
    • @DDDD 真的很奇怪,因为错误日志说你试图从SessionsController 调用sign_in_person...你是否也使用了PersonsController 上的方法?
    • 不,但 PersonsController 是使用 SessionsController 的对象
    【解决方案2】:

    这通常是不好的做法,但您可以在控制器中使用view_context.sign_in_person。我相信您也可以在控制器中使用helper 方法,如下所示:

    class SessionsController < ApplicationController
      helper :sessions
    
      ...
    end
    

    帮助者通常应该是为了视图。就像 raviolicode 所说,您可以将其移动到控制器并使用helper_method 使其可供您的控制器和视图访问。

    # in controller
    def sign_in_person
      ....
    end
    helper_method :sign_in_person
    

    如果您只想在控制器中使用它,最好只在控制器内部创建一个私有方法,或者将其移动到 concern

    【讨论】:

      【解决方案3】:

      如果你想从控制器中调用一个辅助方法,你需要根据它是辅助方法上的类还是实例方法来调用它:

      # app/controllers/sessions_controller.rb
      class SessionsController < ApplicationController
        include SessionsHelper
      
        def create
          person = Person.find_by_email(params[:session][:email].downcase)
          SessionsHelper.sign_in_person person # Class method invocation
          sign_in_person person # Instance method invocation
        end
      
      end
      
      # app/helpers/sessions_helper.rb
      module SessionsHelper
      
        # Instance method
        def sign_in_person(person)
          cookies[:remember_token] = person.remember_token
          SessionHelper.current_person = person
        end
      
        # Class method
        def self.sign_in_person(person)
          cookies[:remember_token] = person.remember_token
          self.current_person = person
        end
      
      end
      

      【讨论】:

        猜你喜欢
        • 2015-10-18
        • 1970-01-01
        • 2020-11-25
        • 2016-08-09
        • 2014-02-16
        • 1970-01-01
        • 1970-01-01
        • 2011-11-19
        • 2013-06-11
        相关资源
        最近更新 更多