Канкан: създайте способност

Имам следния код:

#/app/models/users/user.rb
class Users::User < ActiveRecord::Base
  has_many :phones, class_name: "Users::Phone"
end

#/app/models/users/phone.rb
class Users::Phone < ActiveRecord::Base
  belongs_to :user, class_name: "Users::User"
  attr_accessible :phone
end


#/app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)

    can :read, :all

    unless user.nil? #logged_in
      if user.is? :admin
        can :manage, :all
      else
        can :create, Users::Phone, user_id: user.id
      end
    end

  end
end

Искам да проверя възможността за създаване само на собствени телефони за потребителите

#/app/views/users/users/show.html.slim
- if can? :create, Users::Phone.new
  a[href="/bg#{new_user_phone_path(@user)}"] Add phone

Това не работи, защото трябва да предам user_id на модела на телефона (като Users::Phone.new user_id: user.id), но не мога да направя това след масовото присвояване на Phone.

И така, как мога да проверя възможността за :create телефони за потребителите?


person ole    schedule 04.04.2013    source източник


Отговори (1)


Правя нещо подобно в моето приложение, като уведомявам Ability за основната структура на параметрите. Имате няколко опции в зависимост от вашите изисквания. Така че във вашия контролер ще имате приблизително:

def create
  @phone = Users::Phone.new(params[:users_phone])

  # Optional - this just forces the current user to only make phones 
  # for themselves.  If you want to let users make phones for 
  # *certain* others, omit this.
  @phone.user = current_user

  authorize! :create, @phone
  ...
end

след това във вашите способности.rb:

unless user.nil? #logged_in
  if user.is? :admin
    can :manage, :all
  else
    can :create, Users::Phone do |phone|
      # This again forces the user to only make phones for themselves.
      # If you had group-membership logic, it would go here.
      if phone.user == user
        true
      else
        false
      end
    end
  end
end
person Dave S.    schedule 04.04.2013
comment
Дейв, благодаря за решението, работи според очакванията. За правилна проверка на :create способността в изгледите използвах if can? :create, Users::Phone.new({user: @user}, without_protection: true) където @user е собственик, за когото искаме да създадем телефон. - person ole; 04.04.2013
comment
Благодаря! Тъй като аз обикновено load_and_authorize_resource в горната част на всеки контролер, го промених да бъде: load_and_authorize_resource освен: :create И след това ръчно извиквам авторизацията! и предайте моя обект, както показахте по-горе. - person Emeka; 12.10.2016