Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.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 rails设计了未定义的方法用户名,当我想将其用于cancancan时_Ruby On Rails_Ruby_Devise_Cancan_Cancancan - Fatal编程技术网

Ruby on rails rails设计了未定义的方法用户名,当我想将其用于cancancan时

Ruby on rails rails设计了未定义的方法用户名,当我想将其用于cancancan时,ruby-on-rails,ruby,devise,cancan,cancancan,Ruby On Rails,Ruby,Devise,Cancan,Cancancan,我希望在rails中实现基于角色的授权。对于登录,我使用gem设备,它工作得非常完美。但是在我包括了一些cancancan的代码之后,我得到了一个错误未定义的方法username,当我删除username时,我得到了一个错误未定义的方法email 这是我的密码: ability.rb(管理具有特定角色的用户可以做什么) 我的user.rb的一部分 ROLES = {0 => :admin, 1 => :mitarbeiter} attr_reader :role :

我希望在rails中实现基于角色的授权。对于登录,我使用gem设备,它工作得非常完美。但是在我包括了一些cancancan的代码之后,我得到了一个错误未定义的方法username,当我删除username时,我得到了一个错误未定义的方法email

这是我的密码:

ability.rb(管理具有特定角色的用户可以做什么)

我的user.rb的一部分

      ROLES = {0 => :admin, 1 => :mitarbeiter}

  attr_reader :role :

  def initialize(role_id = 0)
    @role = ROLES.has_key?(role_id) ? ROLES[role_id] : ROLES[0]

  end

  def role?(role_name)
    role == role_name
  end
我的应用程序的一部分\u controller.rb

  protect_from_forgery with: :exception

  check_authorization

  rescue_from CanCan::AccessDenied do |exception|
    flash[:warning] = exception.message
    redirect_to root_path
  end

  private

  def current_user
    User.new(session[:id])
  end

  helper_method :current_user
我真的不知道哪里不对。。。
我原以为我必须在user.rb中设置@user like@role,但这没有帮助

我建议删除
user#initialize
方法和
attr\u reader:role
声明并创建自己的
role
方法,如下所示:

def role
  @role ||= ROLES.has_key?(role_id) ? ROLES[role_id] : ROLES[0]
end

def role?(role_name)
  role == role_name
end
通过这种方式,您可以实现预期目标,但不会覆盖ActiveRecord的
User#initialize
方法


上面的代码假设
role\u id
存储在数据库的
role\u id
列中。

我找到了解决方案,并且角色id也正确地存储在数据库中。以下是我的解决方案:

my new ability.rb(不仅仅是完成功能测试)

新用户.rb

      ROLES = %i[admin mitarbeiter]

  def roles=(roles)
    roles = [*roles].map { |r| r.to_sym }
    self.role_id = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
  end

  def roles
    ROLES.reject do |r|
      ((role_id.to_i || 0) & 2**ROLES.index(r)).zero?
    end
  end

  def has_role?(role)
    roles.include?(role)
  end
新应用程序_controller.rb部分

  def configure_permitted_parameters
    added_attrs = [:username, :email, :password, :password_confirmation, :remember_me, roles: [] ]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end
在这里,我将角色分配给用户views/design/registrations/new.html.erb

    <% for role in User::ROLES %>
      <%= check_box_tag "user[roles][#{role}]", role, @user.roles.include?(role), {:name => "user[roles][]"}%>
      <%= label_tag "user_roles_#{role}", role.to_s.humanize %><br />
    <% end %>
    <%= hidden_field_tag "user[roles][]", "" %>

这个错误发生在哪里?您没有在问题的任何地方调用
username
?啊哦,对不起,我在视图中调用了current_user.username。bevore我和cancancan合作过它成功了…我认为你不应该覆盖ActiveRecord派生模型的
initialize
,至少不需要在其中调用super。我想需要initialize方法来设置角色可以是什么,或者我在这里错了吗?我得到了这个错误:未定义的局部变量或方法'role\u id'必须以某种方式存储用户的角色?您是否在数据库中存储
role\u id
?否我在用户表中获得了一个“role”字段,但这些角色未存储在数据库中。这是个问题吗?您不需要特殊的表来存储用户的角色。用户表中需要一列。IMO数字类型
role\u id
(或任何其他名称),当用户为管理员时,您将在其中存储
0
,当用户为mitarbeiter时存储
1
  def configure_permitted_parameters
    added_attrs = [:username, :email, :password, :password_confirmation, :remember_me, roles: [] ]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end
    <% for role in User::ROLES %>
      <%= check_box_tag "user[roles][#{role}]", role, @user.roles.include?(role), {:name => "user[roles][]"}%>
      <%= label_tag "user_roles_#{role}", role.to_s.humanize %><br />
    <% end %>
    <%= hidden_field_tag "user[roles][]", "" %>
    gem 'devise', github: 'plataformatec/devise'
    gem 'cancancan'