Devise和Cancancan - 如何使它工作?

时间:2016-01-23 11:24:03

标签: ruby-on-rails ruby devise access-control cancancan

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

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

问题是我不明白它是如何完全实现的。 Google缺乏示例和示例,这些示例和示例大多已过时。

这就是我所拥有的:

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

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

Article.rb

class Article
  include Mongoid::Document
  belongs_to :user

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

  default_scope -> { order(created_at: :desc) }
end

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>

1 个答案:

答案 0 :(得分:3)

您需要在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

-

#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>

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

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

我看到很多人发布了关于&#34;授权&#34;使用Devise,当它完全错误时。 Devise只处理身份验证(用户登录?);在处理授权时,您需要使用不同的模式,利用创建的user对象设计。

只是想指出这一点,考虑到你在原帖中提到了Devise