我有一個Rails應用程序有如下型號:軌道4:CanCanCan能力與的has_many:通過關聯
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
對於給定的calendar
,一個user
有role
,這是定義在administration
加盟模式。
對於每個日曆,用戶只能擁有以下三種角色之一:Owner
,Editor
或Viewer
。
這些角色目前沒有存儲在字典或常量中,只通過不同的方法將其分配給字符串(「Ower」,「Editor」,「Viewer」)。
對User
模型的驗證通過Devise進行處理,並且current_user
方法正在工作。
爲了僅允許登錄用戶訪問應用內資源,我已經在calendars
和administrations
控制器中添加了before_action :authenticate_user!
方法。
現在,我需要實現一個基於角色的授權系統,所以我只安裝了CanCanCan
寶石。
這裏是我想達到的目標:
- 所有(登錄)
user
S能創造新的calendar
秒。 - 如果
user
是calendar
的owner
,那麼他就可以manage
屬於此calendar
,包括他自己的administration
和calendar
所有administration
秒。 - 如果用戶是
editor
的calendar
,那麼他可以read
和update
這個日曆,並銷燬他的administration
。 - 如果
user
是calendar
的viewer
,那麼他就可以read
這個calendar
,並且destroy
他administration
。
爲了實現上述,我想出了以下ability.rb
文件:
class Ability
include CanCan::Ability
def initialize(user, calendar)
user ||= User.new
calendar = Calendar.find(params[:id])
user can :create, :calendar
if user.role?(:owner)
can :manage, :calendar, :user_id => user.id
can :manage, :administration, :user_id => user.id
can :manage, :administration, :calendar_id => calendar.id
elsif user.role?(:editor)
can [:read, :update], :calendar, :user_id => user.id
can :destroy, :administration, :user_id => user.id
elsif user.role?(:viewer)
can [:read], :calendar, :user_id => user.id
can :destroy, :administration, :user_id => user.id
end
end
end
因爲我不是很嘗試用Rails和這是我第一次與CanCanCan
工作,我對我的代碼不太有信心,並希望得到一些驗證或改進建議。
那麼,這個代碼是否可以工作,它能讓我實現我所需要的嗎?
UPDATE:使用當前代碼,當我以用戶身份登錄並訪問另一個用戶日曆的日曆#show頁面時,我實際上可以訪問日曆,而我不應該這樣做。
所以,顯然,我的代碼不工作。
任何想法我做錯了什麼?
更新2:我想有在我的代碼中的錯誤,因爲我是用的,而不是:model
到Model
允許user
s到給定model
執行操作。
但是,代碼仍然無法正常工作。
有什麼想法可能是錯誤的嗎?
更新3:可以在問題來的事實,我用if user.role?(:owner)
檢查,如果用戶的角色設置爲所有者,同時在數據庫中的角色實際上是定義爲「所有者」(字符串)引起的?
更新4:我一直在做一些研究,我意識到我犯了兩個錯誤。
我沒有添加
load_and_authorize_resource
到calendars
和administrations
控制器。我已經定義了兩個屬性兩個參數 -
initialize(user, calendar)
- 而不是我的initialize
方法中的一個。
因此,更新兩個控制器,還有ability.rb文件,如下所示:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.role?(:owner)
can :manage, Calendar, :user_id => user.id
can :manage, Administration, :user_id => user.id
can :manage, Administration, :calendar_id => calendar.id
elsif user.role?(:editor)
can [:read, :update], Calendar, :user_id => user.id
can :destroy, Administration, :user_id => user.id
elsif user.role?(:viewer)
can [:read], Calendar, :user_id => user.id
can :destroy, Administration, :user_id => user.id
end
end
end
現在,當我嘗試訪問不屬於current_user
日曆,我拿出現以下錯誤:
NoMethodError in CalendarsController#show
undefined method `role?' for #<User:0x007fd003dff860>
def initialize(user)
user ||= User.new
if user.role?(:owner)
can :manage, Calendar, :user_id => user.id
can :manage, Administration, :user_id => user.id
can :manage, Administration, :calendar_id => calendar.id
我該如何解決這個問題?
這正是我終於實現了。謝謝! –