康康康 has_and_belongs_to_many 的能力

cancancan Abilities with has_and_belongs_to_many

我的 类 用户和页面之间存在以下关系。

class User < ApplicationRecord
  has_and_belongs_to_many :pages
end

class Page < ApplicationRecord
  has_and_belongs_to_many :users
end

如何在我的 Ability 文件中让用户只编辑属于他的页面?

class Ability
  include CanCan::Ability
  def initialize(user)
      if user.is? :page_administrator
        can :manage, Page
      end
  end
end

我试了下面的,还是不行

  can :manage, Page, users: { user_id: user.id }

has_and_belongs_to_many 的最大缺点是无法将数据附加到联接 table。而是使用连接模型:

class User < ApplicationRecord
  has_many :user_pages
  has_many :pages, through: :user_pages
end

class Page < ApplicationRecord
  has_many :user_pages
  has_many :users, through: :user_pages
end

class UserPage < ApplicationRecord
  belongs_to :user
  belongs_to :page
end

这与 has_and_belongs_to_many 类似,只是它不是无头的 - 您可以直接查询 UserPage。除了创建 UserPage 模型之外,您唯一需要做的就是将 table 从 users_pages 重命名为 user_pages(或将 pages_users 重命名为 page_users)。

class RenameUsersPages < ActiveRecord::Migration[5.0]
  def change
    rename_table('users_pages', 'user_pages')
  end
end

这是必需的,因为 rails 将 link 将 table 转换为常量 Users::Page 否则。

现在您可以轻松地在 UserPage table 上附加 admin 标志。

class AddPageAdministratorToUserPages < ActiveRecord::Migration[5.0]
  change_table :users do |t|
    t.boolean :admin, default: false
   end
end

现在我们可以通过检查 user_pages 中是否存在记录来检查用户是否为管理员:

class Ability
  include CanCan::Ability
  def initialize(user)
      can :manage, Page do |p|
        p.user_pages.exists?(admin: true, user: user)
      end
  end
end