1

、、を使用したRubyonRailsアプリがusersありarticlesますcollaborations。関係は次のとおりです。

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問題は...管理者ではないユーザーがコラボレーションの一部である記事で引き続きコラボレーションできるように、その役割をファイルに書き込むにはどうすればよいですか?」

  1. ユーザーA(管理者)がArticleXを作成します
  2. ユーザーAは、ユーザーBとの記事Xに関するコラボレーションを作成します
  3. ユーザーBはログインしますが、ArticleXの編集と更新のみが可能です。

どのようにそれを書くべきですか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
4

5 に答える 5

5

これがあなたのために働くかもしれないあなたの能力クラスの論理です:

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を使用すると、関連付けの条件を指定できます。ここでは、の関連付けの:user_id条件を渡します。:collaborationsArticle

ユーザーに追加された追加のメソッド:

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
于 2012-10-07T23:45:45.780 に答える
1

あなたのability.rbファイルでこのようなことを試すことができます。ユーザーテーブルで役割を定義するだけで、モデルファイルの列挙型として使用できます

:role, ["管理者", "ゲスト", "その他"]

if user.role == "Admin"
      if user.role == "admin"
            can :manage, :all
      else
           can :read, Article
      end
end
于 2012-10-08T13:08:38.873 に答える
0

次の方法で試してください。

def initialize(user)

user ||= User.new
if user.admin?
    can :manage :all
elsif user.registered?
    can :manage, Article, :collaborations=>{:user_id=>user.id}
    can :read,  Article
else
    can :read,  Article
end

終わり

于 2012-10-10T07:32:25.653 に答える
0

試す

can :manage, Article, :collaborations => {:user_id => user.id}
于 2012-10-05T13:41:17.357 に答える
0

これは、CanCan の作成者によるビデオ ガイドで、gem の正しい使用法を明確にする可能性があります。

http://railscasts.com/episodes/192-authorization-with-cancan

すべてのアクセス許可を設定した後、コントローラーで現在のユーザーが実行したアクションを承認することを忘れないでください。githubに関するその他のドキュメント。

約1年前にCanCanを使用しましたが、コマンドで簡単に設定できましたload_and_authorize_resource

Class ArticlesController > ApplicationController
  load_and_authorize_resource #authorize all actions based on ability.rb

  def index
    ## manual authorization ##
    @articles = Article.all
    authorize! :read, @articles #Manually authorize this action. You dont need this if you put load_and_authorize_resource on top. 
    ## end manual authorization ##
  end

  def show 
    #@article = Article.find(params[:id]) #already loaded and authorized through load_and_authorize_resource
  end

end

コーヒーをお楽しみください。

于 2012-10-10T13:51:22.580 に答える