Devise 和 Cancancan - 如何让它发挥作用?

Fre*_*esz 3 ruby ruby-on-rails access-control devise cancancan

我正在制作一个网络应用程序(聊天之类的东西),因为昨天我从 Pundit (因为它太难了)切换到 Cancancan (它对我来说看起来更好)。

我正在尝试使一些简单的工作变得简单,例如显示所有文章及其选项(显示、编辑、销毁),然后对其设置权限,以便创建此类文章的唯一用户将能够编辑或销毁它。

问题是我不明白它是如何完全实施的。谷歌缺乏示例,而且大多数示例都已过时。

这是我所拥有的:

ability.rb - 我不知道这是否正确

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.admin?
        can :manage, :all
    else
        can :read, :all
    end

    can :read, :articles
    can :create, :articles
  end
end
Run Code Online (Sandbox Code Playgroud)

User.rb(设计)

class User
  include Mongoid::Document
  has_many :articles
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  ## Database authenticatable
  field :username,               type: String, default: ""
  field :email,              type: String, default: ""
  field :encrypted_password, type: String, default: ""

  ## Recoverable
  field :reset_password_token,   type: String
  field :reset_password_sent_at, type: Time

  ## Rememberable
  field :remember_created_at, type: Time

  ## Trackable
  field :sign_in_count,      type: Integer, default: 0
  field :current_sign_in_at, type: Time
  field :last_sign_in_at,    type: Time
  field :current_sign_in_ip, type: String
  field :last_sign_in_ip,    type: String

  ## Admin
  field :admin, :type => Boolean, :default => false
end
Run Code Online (Sandbox Code Playgroud)

文章.rb

class Article
  include Mongoid::Document
  belongs_to :user

  field :title, type: String
  field :content, type: String

  default_scope -> { order(created_at: :desc) }
end
Run Code Online (Sandbox Code Playgroud)

index.html(显示文章 - 仅我添加 Cancancan 的部分)

<tbody>
   <% @articles.each do |article| %>
     <tr>
       <td><%= article.title %></td>
       <td><%= article.content %></td>
       <td><%= link_to 'Show', article %></td>
       <td>
          <% if can? :update, @article %>
             <%= link_to 'Edit', edit_article_path(article) %>
          <% end %>
       </td>
       <td><%= link_to 'Destroy', article, method: :delete, data: { confirm: 'Are you sure?' } %></td>
              </tr>
            <% end %>
          </tbody>
Run Code Online (Sandbox Code Playgroud)

Ric*_*eck 5

您需要在文件中按类别Ability定义您的权限:

#app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.admin?
        can :manage, :all
    else
        can :read, :all
    end

    can [:credit, :edit, :update, :destroy], Article, user_id: user.id
  end
end
Run Code Online (Sandbox Code Playgroud)

--

#app/views/articles/index.html.erb
<tbody>
   <% @articles.each do |article| %>
     <tr>
       <td><%= article.title %></td>
       <td><%= article.content %></td>
       <td><%= link_to 'Show', article %></td>
       <td><%= link_to 'Edit', article if can? :update, article %></td>
       <td><%= link_to 'Destroy', article, method: :delete, data: { confirm: 'Are you sure?' } if can? :destroy, article %></td>
      </tr>
    <% end %>
</tbody>
Run Code Online (Sandbox Code Playgroud)

顺便说一句,要考虑的第二个重要因素是Devise= 身份验证;CanCanCan=授权:

  • 身份验证= 用户是否已登录?
  • 授权 =用户可以这样做吗?

我看到很多人发布有关“授权”的帖子Devise,但这是完全错误的。Devise只处理身份验证(用户登录?);在处理授权时,您需要使用不同的模式,利用userDevise 创建的对象。

只是想指出这一点,考虑到您Devise在原始帖子中提到过。