2012-01-20 11 views
6

Konfiguruję użytkowników admin, którzy należą do klasy klienta (Klient to firma). Klient ma wielu administratorów.Szyny 3 ActiveAdmin CanCan. Jak skonfigurować, że użytkownik powinien widzieć tylko te zapisy, które do niego należą?

Próbuję ograniczyć dostęp do rekordów wysyłek należących do określonego klienta. Nie chcę, aby klienci oglądali dane innych klientów. Więc to skonfigurować, ale wydaje się nie robić nic ...

klasy Możliwość zawierać CanCan :: Możliwość

def initialize(user) 
    user ||= AdminUser.new  
    if user.role == "administrator" 
     can :manage, :all 
    else 
     cannot :create, :all 
     cannot :update, :all 
     cannot :destroy, :all 
     can :read, Shipment do |shipment| 
     shipment.customer == user.customer 
     end 
    end 
    end 
end 

I mam to w shipments.rb ...

ActiveAdmin.register Shipment do 
    menu :if => proc{ can?(:read, Shipment) }, :priority => 1 
    controller.authorize_resource 

    index do 
    column "File #", :sortable => :file_number do |shipment| 
     link_to shipment.file_number, admin_shipment_path(shipment) 
    end 
    [... more columns ...] 
    default_actions if can? :manage, Shipment 
    end 

    show :title => :file_number do 
    panel "Shipment Details" do 
    attributes_table_for shipment do 
    row("File number") {shipment.file_number} 
    row("Mode") {shipment.mode} 
    row("Ocean Rate") { number_to_currency shipment.ocean_rate} 
    row("Customer") { link_to shipment.customer.company_name, admin_customer_path(shipment.customer)} 
    row("Shipper") { link_to shipment.shipper.company_name, admin_shipper_path(shipment.shipper)} 
    row("Broker") { link_to shipment.broker.company_name, admin_broker_path(shipment.broker)} 
    end 
end 

[...more show action stuff...] 

Tak więc na stronie indeksu wyświetlane są wszystkie przesyłki, a jeśli jestem zalogowany jako Klient A i kliknę przesyłkę klienta B, widzę ją, ale powinna mnie zablokować.

Więcej informacji ...

shipments_controller.rb 
class ShipmentsController < InheritedResources::Base 
    before_filter :authenticate_admin_user! 
end 

Odpowiedz

0

Nie wiem, dlaczego to nie działa, ale can? :read, Shipment nie patrzeć uprawnienia do can :read, Shipment do |shipment| ....

Aby potwierdzić to uprawnienie, należy określić konkretne wystąpienie przesyłki, na przykład can :read, @shipment.

Musisz znaleźć sposób, by uzyskać egzemplarz odebranej przesyłki przed wywołaniem linii menu :if => ....


Czy spróbować użyć controller.load_and_authorize_resource zamiast tylko authorize_resource?

+0

Tried to według docs i nie działa albo dlatego każdy użytkownik może zobaczyć żadnych przesyłek ' can: show, Shipment,: customer_id => user.customer_id' https://github.com/ryanb/cancan/wiki/defining-abilities – leonel

+0

Twoja definicja uprawnień jest w porządku, to twoje 'menu: if => ...' coś, co nie działa, może mógłbyś podać nam więcej kontekstu, w jaki sposób jest używany w pliku 'shipments.rb' (czy na pewno nie ma go w' shipments_controller.rb'?). – mbillard

+0

Dodałem więcej informacji w pytaniu. To, co robi linia 'menu: id =>' to po prostu ukryj lub pokaż menu, jeśli użytkownik powinien mieć do niego dostęp, nie sądzę, że to jest problem. Dostaję wszystkie wymienione rekordy, jeśli kliknę jeden z rekordów, których użytkownik NIE powinien zobaczyć, nadal będzie wyświetlany i oczekuję, że CanCan powie mi odmowę dostępu. – leonel

1

Miałem podobny problem w mojej aplikacji. Miałem super_users i administratorów, gdzie administratorzy mogli widzieć tylko innych administratorów w swojej organizacji.

app/models/ability.rb

if user.organization_admin? 
    can :manage, User, :organization_id => user.organization_id 
end 

app/admin/users.rb

controller do load_and_authorize_resource :except => :index 
    def scoped_collection 
    end_of_association_chain.accessible_by(current_ability) 
    end 
end 
0

Użyj scoped kolekcji i uruchomić kwerendę, która zależy od aktualnej zalogowanym użytkownikiem

ActiveAdmin.register Shipment do 
    controller do 
    def scoped_collection 
     my_scope = resource_class.unscoped 
     return my_scope if current_admin_user.role == "administrator" # return everything 
     my_scope.where(customer_id: current_admin_user.customer_id) # filter by signed in user 
    end 
    end 
end 
Powiązane problemy