2016-06-05 15 views
0

company.rb has_many:Schienen cancancan durch Fähigkeiten

class Company < ActiveRecord::Base 
    has_many :companies_admins, dependent: :destroy 
    has_many :supervisors, through: :companies_admins 
end 

companies_admin.rb:

class CompaniesAdmin < ActiveRecord::Base 
    belongs_to :company 
    belongs_to :supervisor, foreign_key: "admin_id" 
end 

supervisor.rb:

class Supervisor < Admin 
    has_many :companies_admins, foreign_key: "admin_id" 
    has_many :companies, through: :companies_admins, foreign_key: "admin_id" 
end 

i cancancan gem verwenden. Mein ability.rb:

class Ability 
     include CanCan::Ability 

     def initialize(user) 
     user ||= Admin.new # guest user (not logged in) 
     if user.type == "Administrator" 
      can :manage, :all 
     elsif user.type == "Supervisor" 
      can :manage, Company, companies_admins: {supervisor: { :id => user.id } } 
     end 
    end 
end 

companies_controller.rb:

class CompaniesController < ApplicationController 
    load_and_authorize_resource only: [:new, :create, :edit, :update, :index, :show, :destroy] 
    load_and_authorize_resource :supervisor 
    load_and_authorize_resource through: :supervisor 
... 
end 

ich Supervisor brauchen nur Unternehmen in der Lage zu verwalten, mit der er eine Beziehung hat. Beispiel: supervisor

companies_admins

wenn ich öffnen Sie die Seite der Firma id = 10 erhalten Zugriff verweigert.

Started GET "/companies/10" for 127.0.0.1 at 2016-06-05 14:23:01 +0300 
Processing by CompaniesController#show as HTML 
    Parameters: {"id"=>"10"} 
    Company Load (0.4ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT 1 [["id", 10]] 
    Admin Load (0.3ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" = $1 LIMIT 1 [["id", 4]] 
    CompaniesAdmin Load (0.4ms) SELECT "companies_admins".* FROM "companies_admins" WHERE "companies_admins"."company_id" = $1 [["company_id", 10]] 
    Supervisor Load (0.4ms) SELECT "admins".* FROM "admins" WHERE "admins"."type" IN ('Supervisor') AND "admins"."id" = $1 LIMIT 1 [["id", 2]] 
    Supervisor Load (0.4ms) SELECT "admins".* FROM "admins" WHERE "admins"."type" IN ('Supervisor') AND "admins"."id" = $1 LIMIT 1 [["id", 4]] 
Redirected to http://localhost:3000/ 
Completed 302 Found in 20ms (ActiveRecord: 1.9ms) 

Die Frage ist warum? Wie erkennt man den Ausdruck "include"?

Edit: Sehr seltsam, auch vom Administrator, bekomme ich Zugriff verweigert, wenn zu ersetzen: alle Unternehmen. Warum?

def initialize(user) 
    user ||= Admin.new # guest user (not logged in) 
    puts user.type 
    if user.type == "Administrator" 
     can :manage, Company 
    elsif user.type == "Supervisor" 
     can :show, :all 
    end 
end 

Started GET "/companies/10" for 127.0.0.1 at 2016-06-05 22:55:49 +0300 
Processing by CompaniesController#show as HTML 
    Parameters: {"id"=>"10"} 
    Admin Load (0.3ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" = $1 LIMIT 1 [["id", 1]] 
Administrator 
Redirected to http://localhost:3000/ 
Completed 302 Found in 42ms (ActiveRecord: 2.5ms) 

in Schienen Konsole:

irb(main):005:0> mi = Admin.find(1) 
    Admin Load (0.7ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" = $1 LIMIT 1 [["id", 1]] 
=> #<Administrator id: 1, type: "Administrator", login: "mars", crypted_password: "8d6ff3f5b32b22726a45b1f8fa69519debf9ec8157d78f8e41...", password_salt: "2oMqwXKIukbKpdEXip", persistence_token: "37127e1f262d4efb44bc458df76e110a6ee78969c94c84a43c...", created_at: "2016-06-04 21:11:18", updated_at: "2016-06-05 09:06:15"> 
irb(main):006:0> comp = Company.find(10) 
    Company Load (0.9ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT 1 [["id", 10]] 
=> #<Company id: 10, parent_id: nil, address_id: 6, name: "test_address"...> 
irb(main):007:0> ability = Ability.new(mi) 
Administrator 
=> #<Ability:0x007f09513a0938 @rules=[#<CanCan::Rule:0x007f09513a0898 @match_all=false, @base_behavior=true, @actions=[:manage], @subjects=[Company(id: integer, parent_id: integer, address_id: integer, name: string, info: string, created_at: datetime, updated_at: datetime, site_link: string, vk_link: string, raiting: float, city_id: integer, paid: integer)], @conditions={}, @block=nil>], @rules_index={Company(id: integer, parent_id: integer, address_id: integer, name: string, info: string, created_at: datetime, updated_at: datetime, site_link: string, vk_link: string, raiting: float, city_id: integer, paid: integer)=>[0]}> 
irb(main):008:0> ability.can?(:manage, comp) 
=> true 

Was habe ich falsch gemacht?

Antwort

1

hmm, ist, dass es funktioniert:

class Ability 
    include CanCan::Ability 
    def initialize(user) 
    user ||= Admin.new # guest user (not logged in) 
    if user.type == "Administrator" 
     can :manage, Company 
    elsif user.type == "Supervisor" 
     can :manage, Company do |comp| 
      comp.supervisor_ids.include?(user.id) 
     end 
    end 
    end 
end 

companies_controller.rb:

class CompaniesController < ApplicationController 
    load_and_authorize_resource only: [:new, :create, :edit, :update, :index, :show, :destroy] 
.... 
+0

Das jetzt hier erwähnt geändert worden ist, wie: https://github.com/CanCanCommunity/cancancan/wiki/ Verschachtelte Ressourcen # has_many-through-associations –