Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.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:使用CanCan根据单个模型的实例定义多个角色?_Ruby On Rails_Ruby_Authorization_Cancan - Fatal编程技术网

Ruby on rails Rails:使用CanCan根据单个模型的实例定义多个角色?

Ruby on rails Rails:使用CanCan根据单个模型的实例定义多个角色?,ruby-on-rails,ruby,authorization,cancan,Ruby On Rails,Ruby,Authorization,Cancan,我目前一直在研究如何根据我们想要的每种情况来区分CanCan的角色。 在我们的应用程序中,有许多类别(如数学、英语、历史等),每个类别中都有许多课程 每个用户在每个类别上可以有许多不同的角色。例如,约翰可以成为数学的“读者”,这意味着他可以阅读所有的数学课程。John还可以成为英语的“作者”,这意味着他可以阅读所有英语课程,在英语类别中创建课程,并且只编辑/删除他在英语类别中创建的课程 如果这些是John仅有的角色,他将无法在导航栏中查看类别历史,并且将被拒绝访问历史中的课程 以下是建立关系的方

我目前一直在研究如何根据我们想要的每种情况来区分CanCan的角色。 在我们的应用程序中,有许多类别(如数学、英语、历史等),每个类别中都有许多课程

每个用户在每个类别上可以有许多不同的角色。例如,约翰可以成为数学的“读者”,这意味着他可以阅读所有的数学课程。John还可以成为英语的“作者”,这意味着他可以阅读所有英语课程,在英语类别中创建课程,并且只编辑/删除他在英语类别中创建的课程

如果这些是John仅有的角色,他将无法在导航栏中查看类别历史,并且将被拒绝访问历史中的课程

以下是建立关系的方式:

class User < ActiveRecord::Base
  has_many :roles

  def has_role?(role_sym)
    roles.any? { |r| r.level.underscore.to_sym == role_sym }
  end
end

class Category < ActiveRecord::Base
  has_many :roles
  has_many :courses
end

class Role < ActiveRecord::Base
  belongs_to :user
  belongs_to :category
  attr_accessible :level, :category_id, :user_id
end
问题:

  • 我们如何正确区分“读者”和“作者”的角色?我们如何访问我们可以访问的类别中的课程

  • 在ability.rb中定义了reader和writer方法之后,我们如何在视图页面中使用它们?看起来当前的文档使用了类似于“ “但这并没有使用我们分离和定义的方法

  • p、 我们将有7个不同的角色:来宾、读者、作者、编辑、经理、管理员和应用程序管理员(我们的开发者)


    我已经试着解决这个问题3天了-请理解,我仍然是一个初学者!提前感谢

    在您的GEM文件中包括

  • 宝石“坎坎”

  • 安装捆绑包

  • 坎坎:能力

  • 这将在您的模型中生成一个能力类

    在这里定义你的能力,如下所示

    但请记住,您已经定义了角色

    比如你有一个用户模型

    定义了两个角色,即管理和支持

      class Ability
          include CanCan::Ability
           def initialize(user)
             user||= User.new
               can :read, :all
           if user.role == 'admin'
              can :manage, :all
           else
              can :read, :all
              end
           end
        end
    
    四,。要限制用户的资源, 在其控制器中使用以下过滤器

                  load_and_authorize_resource
    
    五,。如果要限制视图中的某些内容不显示

        <% if can? :manage, @flower %>
         <td><%= link_to 'Edit', edit_flower_path(flower) %></td>
        <% end %>
        <% if can? :manage, @flower %>
          <td><%= link_to 'Destroy', flower_path(flower), method: :delete, data: { confirm: 'Are you sure?' } %></td>
        <% end %>
    

    今天,我遇到了同样的需求,并找到了一种在计算机上实现这一点的方法

    请按照以下简单步骤进行操作:

    1) 使用您的角色名称在User类下创建一个常量:

    class User < ActiveRecord::Base
      ROLES = %w[admin moderator author banned]
    end
    
    2b)如果使用Mongoid,请在用户模型上添加以下字段:

    field :roles_mask, type: Integer
    
    3) 接下来,您需要将以下代码添加到用户模型中:

    # in models/user.rb
    def roles=(roles)
      self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
    end
    
    def roles
      ROLES.reject do |r|
        ((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero?
      end
    end
    
    4) 如果您使用的是没有强参数的Desive,请不要忘记将attr_accessible:角色添加到您的用户模型中。如果您正在使用带有强_参数的Desive,无论是作为Rails 3应用程序中的gem,还是Rails 4中内置的gem,请不要忘记将角色添加到控制器中的允许列表中:

    class ApplicationController < ActionController::Base
      before_filter :configure_permitted_parameters, if: :devise_controller?
    
      protected
    
      def configure_permitted_parameters
        devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])}
      end
    end
    
    就这样

    我希望这能有所帮助

    # in models/user.rb
    def roles=(roles)
      self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
    end
    
    def roles
      ROLES.reject do |r|
        ((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero?
      end
    end
    
    class ApplicationController < ActionController::Base
      before_filter :configure_permitted_parameters, if: :devise_controller?
    
      protected
    
      def configure_permitted_parameters
        devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])}
      end
    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.humanize %><br />
    <% end %>
    <%= hidden_field_tag "user[roles][]", "" %>
    
    # in models/user.rb
    def is?(role)
      roles.include?(role.to_s)
    end
    
    # in models/ability.rb
    can :manage, :all if user.is? :admin