我有一个 Ruby on Rails 应用,包含用户
、文章
和协作
。以下是关系:
User has_many :articles
User has_many :collaborations
Article belongs_to :users
Article has_many :collaborations
# Collaboration has collaboration.id collaboration.user_id and collaboration.article_id.
Collaboration belongs_to :users
Collaboration belongs_to :articles
通过协作,我成功地访问了用户和文章,所以我认为我的应用程序中的所有设置都正确无误。好的问题。
我正在使用 CanCan角色为 :admin
。基本上我只希望 :admin
能够创建帖子和协作,并且我也能正常工作。问题是......我如何将该角色写入我的 ability.rb
文件,以便非管理员用户仍然可以在他们参与协作的文章中进行协作?”
- 用户 A(管理员)创建文章 X
- 用户 A 与用户 B 就文章 X 创建了协作
- 用户 B 登录但只能编辑和更新文章 X
我应该如何在 ability.rb
中编写它。这就像我想说的:“不是管理员的用户可以管理文章,他们是该文章协作的一部分。”
抱歉啰嗦,我还没喝咖啡:)。这是我的 ability.rb
。
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.role == "admin"
can :manage, :all
else
can :read, Article
# this is where I want to say: can :manage if part of collaboration for article
end
end
end
最佳答案
以下是您的 Ability 类中可能适合您的逻辑:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
case
when user.admin?
can :manage, :all
when user.registered?
can :read, Article
can :manage, Article, :collaborations => { :user_id => user.id }
else # user.guest?
can :read, Article
end
end
end
CanCan 允许您指定关联的条件;在这里,我们为 Article
上的 :collaborations
关联传递了 :user_id
条件。
为用户添加的附加方法:
class User < ActiveRecord::Base
ROLES = [
ADMIN = 'admin'
]
def admin?
role == ADMIN
end
def registered?
persisted?
end
end
为确保它正常工作,下面是您可以如何使用 RSpec、FactoryGirl 和 CanCan 匹配器编写测试:
require 'spec_helper'
require "cancan/matchers"
describe Ability do
subject { Ability.new(user) }
context "admin" do
let(:user) { create(:admin) }
it { should be_able_to(:manage, :all) }
end
context "user" do
let(:user) { create(:user) }
it { should be_able_to(:read, Article) }
it "cannot manage articles without collaborations" do
article = create(:article)
should_not be_able_to(:manage, article)
end
it "cannot manage articles only others collaborated on" do
article = create(:article)
article.collaborations.create { |c| c.user = create(:user) }
should_not be_able_to(:manage, article)
end
it "can manage article with collobaration" do
article = create(:article)
article.collaborations.create { |c| c.user = user }
should be_able_to(:manage, article)
end
end
context "guest" do
let(:user) { User.new }
it { should be_able_to(:read, Article) }
it { should_not be_able_to(:manage, Article) }
end
end
关于ruby-on-rails - CanCan、Rails 和协作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12747313/