2012-05-24 3 views
1

У меня есть пользователиКанкан - новая форма терпит неудачу, когда пользователь ограничен определенным сайтам

class User < ActiveRecord::Base 
    devise :database_authenticatable, 
     :recoverable, :rememberable, :trackable, :validatable 


    attr_accessible :email, :password, :password_confirmation, 
        :remember_me, :site_id, :role_name 

    belongs_to :site 

end 

сайты

class Site < ActiveRecord::Base 
    has_many :users 
    has_one :front_page_campaign 
end 

и front_page_campaigns

class FrontPageCampaign < ActiveRecord::Base 
    belongs_to :site 
end 

Я использую канкан, чтобы ограничить доступ, поэтому пользователи могут управлять только front_page_campaigns для своего собственного сайта:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new # guest user (not logged in) 

    case user.role_name 

    when "super_admin" 
     # can do everything 
     can :manage, :all 

    when "editor" 
     # can edit content for their site 
     can [:create, :read, :update], FrontPageCampaign, site_id: user.site_id 

    end 
    end 
end 

Это отлично работает для пользователей с ROLE_NAME super_admin, а также для editor на шоу и редактировать на front_page_campaigns. Но когда editor пытается создать новый front_page_campaign, я получаю канкан запрещенного уведомление

You are not authorized to access this page. 

Стандартная форма предлагает выпадающий список всех сайтов, и я думаю, мне нужно, чтобы ограничить это только собственному сайт пользователя. Как мне это сделать?

ответ

1

Ваш вопрос авторизации решается путем добавления:

can :new, FrontPageCampaign 

раздел редактор канкан способности инициализации. Чтобы установить site_id на новый и создать объект, который вы можете настроить before_filter:

# FrontPageCampaignsController 
before_filter :set_site_id, :only => [:new, :create] 

protected 

def set_site_id 
    @resource.site_id = current_user.site_id if current_user && current_user.role_name == 'editor' 
end 

Вы должны убедиться, что это срабатывает после того, как ресурс создан, но прежде, чем может законсервировать авторизации.

В вашей форме (если вы используете то же самое для суперадмина и редактора), сделайте выбор выпадающего списка сайта только для чтения или скрытым, если current_user.role_name == 'editor'.

Обратите внимание, что если кто-то замаскирует форму и отправляет иностранец site_id в качестве редактора, он будет исправлен фильтром before, что не очень приятно. Если вы возьмете, если внесите :only => :new, тогда они получат ошибку авторизации cancan. Если вы супер педант, вместо этого вы должны получить действительный ответ с ошибкой проверки. Вы можете достичь этого: 1) применение before_filter только к новому и 2) говорят в способности инициализация

when "editor" 
    # can edit content for their site 
    can [:read, :update], FrontPageCampaign, site_id: user.site_id 
    can [:create, :new], FrontPageCampaign 
end 

и 3) добавить владелец сайта проверку модели проверки. Это мой предпочтительный способ, сохраняя ошибки авторизации для незаконного доступа к существующим ресурсам.

надеюсь, что это ответит на ваш вопрос

+0

Спасибо за подробный ответ. Я думал, что ': create' был псевдонимом, чтобы включить': new', но это наоборот! – Edward

Смежные вопросы