【问题标题】:Pass variables to view within Devise传递变量以在设计中查看
【发布时间】:2014-05-29 04:40:34
【问题描述】:

我正在使用设计 3.2.4。我用这个覆盖 SessionsController:

  def create
    super do |resource|
      @just_signed_in = true
    end
  end

目标是能够在视图中使用变量@just_signed_in 来触发仅应在登录时调用的前端JavaScript。这是我的after_sign_in_path_for(resource) 的定义方式:

  def after_sign_in_path_for(resource)
    return root_path
  end

鉴于return root_path,我认为不允许将@just_signed_in 传递给视图。用户登录后如何触发 JavaScript?我错过了什么吗?

干杯,

【问题讨论】:

    标签: javascript ruby-on-rails devise


    【解决方案1】:

    我认为您的变量对视图不可用的原因是因为respond_with 由设计的create 在屈服于设置@just_signed_in 的块后执行。如果一切顺利,那么这个respond_with 将执行redirect_to,因此您的@just_signed_in 变量将无法用于处理您的root_path 的控制器(请参阅rails 动作包中ActionController 模块中的navigation_behaviour()actionpack/lib/controller/metal 中显示redirect_to 成功或render 失败)。

    解决此问题的一种方法是按照 Rich 的建议向您的 resource 添加一个属性,然后您可以在视图中使用 current_user 获取它并检查/重置它(理想情况下使用模型中的逻辑而不是看法)。如果您不想向资源/模型添加属性,另一种方法是将“刚刚登录”标志放在会话中,然后在视图中访问/删除它。即代替:

    @just_signed_in = true
    

    有:

    session[:just_signed_in] = true
    

    然后在您看来,执行以下操作:

    if session.delete(:just_signed_in)
      …whatever…
    end
    

    您可能希望将其隐藏在视图助手中,尤其是当您在多个地方需要它时。

    【讨论】:

    • 请注意,您发布的语法无效。我需要这样做:session.delete(:just_signed_in) 用括号代替括号。
    【解决方案2】:

    ThisDevise sessions#create 的来源:

    def create
        self.resource = warden.authenticate!(auth_options)
        set_flash_message(:notice, :signed_in) if is_flashing_format?
        sign_in(resource_name, resource)
        yield resource if block_given?
        respond_with resource, location: after_sign_in_path_for(resource)
    end
    

    --

    问题

    我认为您的问题将是您在设置 @just_signed_in 变量之前调用 super。据我所知,以这种方式调用super 将调用您尝试附加的整个方法[需要研究如何使用super do |var|]...

    如果我的理论是正确的,这意味着您的 @just_signed_in 变量没有被设置,从而导致它无法使用。我最初假设after_sign_in_path_for 将是redirect,但由于它只是设置位置,它应该设置变量如果它正确完成

    更新

    我后来找到了reference you used

    class Admins::SessionsController < Devise::SessionsController
      def create
        super do |resource|
          BackgroundWorker.trigger(resource)
        end
      end
    end
    

    修复

    你需要做几件事:

    确保您的 sessions_controller 覆盖工作正常

    你还没有为你的sessions_controller 发布你的班级声明。这可能看起来很简单,但最简单的事情往往会导致最大的错误!

    你需要有这个:

    #config/routes.rb
    devise_for :users, controllers: { sessions: "your/sessions" }
    
    #app/controllers/sessions_controller.rb
    Class SessionsController < Devise::SessionsController
       ... 
    end
    

    -

    确保您的 @just_signed_in 变量已设置

    由于多种原因(重定向等),您的变量可能在视图中不可用。我强烈建议设置一些logs 来跟踪您是否设置了@just_signed_in 变量:

    #app/controllers/sessions_controller.rb
    def create
       super do |resource|
           @just_signed_in = true
           Rails.logger.info(@just_signed_in.inspect)
       end
    end
    

    这至少可以确认变量是否已设置(因此会有其他问题)

    -

    查看@just_signed_in 的可用位置

    在第二步之后,我会尝试查看@just_signed_in 的可用位置。为此,我会将值附加到您的 resource,然后在您的 after_sign_in_path_for(resource) 方法中使用 logger

    #app/models/user.rb
    Class User < ActiveRecord::Base
       attr_accessor :just_signed_in
    end
    
    #app/controllers/sessions_controller.rb
    def create
        super do |resource|
            resource.just_signed_in = true
        end 
    end
    
    def after_sign_in_path_for(resource)
        Rails.logger.info(resource.just_signed_in.inspect)
    end
    

    我希望这会有所帮助 - 我不知道这是否会奏效,但它肯定会创造一个更好的环境来发现答案!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-05
      • 2012-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多