Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 私有方法中的实例变量在公共控制器方法中为零_Ruby On Rails_Ruby On Rails 4 - Fatal编程技术网

Ruby on rails 私有方法中的实例变量在公共控制器方法中为零

Ruby on rails 私有方法中的实例变量在公共控制器方法中为零,ruby-on-rails,ruby-on-rails-4,Ruby On Rails,Ruby On Rails 4,我正在尝试创建一个帮助器方法,以检查登录用户是否有权使用某些功能,如新建,创建,编辑,更新,以及销毁 当它进入视图时,这是有效的,但是我想阻止聪明的用户通过简单地键入正确的url来创建新的游戏 在我的控制器中,我有: before_action :is_admin, only: [:index, :platform, :publisher, :new, :edit, :create, :update, :destroy] def destroy if !@admin @game.d

我正在尝试创建一个帮助器方法,以检查登录用户是否有权使用某些功能,如
新建
创建
编辑
更新
,以及
销毁

当它进入视图时,这是有效的,但是我想阻止聪明的用户通过简单地键入正确的url来创建新的
游戏

在我的控制器中,我有:

before_action :is_admin, only: [:index, :platform, :publisher, :new, :edit, :create, :update, :destroy]

def destroy
  if !@admin
    @game.destroy
    respond_to do |format|
      format.html { redirect_to games_url }
      format.json { head :no_content }
    end
  else
    redirect_to @game, notice: 'User not authorized to delete games.'
  end
end

def is_admin
  @admin = current_user.roles.detect {|r| r.name == "Super Admin" || r.name == "Game Admin"}
end
通过使用调试器,我可以看到实际上正在调用私有方法,但在公共方法中
@admin
为null

我怀疑这是因为实例变量是在私有空间中声明的,但是如果它对视图可用,为什么它对控制器不可用

无论如何,如果任何人有任何建议,或正确的方法来做我想做的事,我将不胜感激


谢谢。

没有必要缓存
@admin
,因为
当前用户已被缓存。或者,如果当前用户未被缓存,则也不需要缓存admin

基于当前代码,检查角色的一个更简单的方法是设置它的模型级别

class User < ActiveRecord::Base
  def admin?
    role.match /admin/i
  end
end

好的,我想出了一个更好的方法,现在它正在发挥作用。所以,对于所有那些在谷歌上遇到困难的人,以下是我所做的

在我的ApplicationController中,我创建了一些新的助手方法:

class ApplicationController < ActionController::Base

  helper_method :current_user
  helper_method :is_super_admin
  helper_method :is_game_admin

  private

  def current_user
    @current_user ||= Member.find(session[:member_id]) if session[:member_id]
  end

  def is_super_admin
    unless current_user.nil?
      current_user.roles.detect {|r| r.name == "Super Admin"} unless current_user.roles.nil?
    end
  end

  def is_game_admin
    unless current_user.nil?
      current_user.roles.detect {|r| r.name == "Game Admin"} unless current_user.roles.nil?
    end
  end
end

是什么让你认为
@admin
is\u admin
分配了一个非零值?这看起来是一个更好的处理方法,谢谢。但是,我在哪里可以找到有关
match
方法的文档。@SnareChops,如果您想使用该方法一次并仅区分admin,那么该方法就可以了,有关更多规则,最好检查CanCan。对于match doc,这里是:我刚刚注意到您的角色不是用户表中的字段,而是另一个字段,因此特定代码需要根据您的设置进行更改。不管怎么说,原则是一样的,这样的工作应该在模型级别完成。是的,因为用户可以有多个角色,而且一个角色可以有多个用户,所以我创建了一个多个关系以实现灵活性。
class ApplicationController < ActionController::Base

  helper_method :current_user
  helper_method :is_super_admin
  helper_method :is_game_admin

  private

  def current_user
    @current_user ||= Member.find(session[:member_id]) if session[:member_id]
  end

  def is_super_admin
    unless current_user.nil?
      current_user.roles.detect {|r| r.name == "Super Admin"} unless current_user.roles.nil?
    end
  end

  def is_game_admin
    unless current_user.nil?
      current_user.roles.detect {|r| r.name == "Game Admin"} unless current_user.roles.nil?
    end
  end
end
class GamesController < ApplicationController
  before_action :is_admin, only: [:new, :edit, :create, :update, :destroy]

  #... controller methods

  private

  def is_admin
    unless is_super_admin || is_game_admin
      redirect_to games_url, notice: 'User is not authorized to perform this function.'
    end
  end
end