2012-12-30 12 views
5

Zobaczmy, czy potrafię wystarczająco dobrze wyjaśnić wątpliwości, które mam.Mylić o zagnieżdżonych zasobach i uwierzytelnianiu w Railsach

Mam model użytkownika zarządzany przez program Devise. Tak więc w moich trasach mam:

devise_for :users 

W użytkownika modelu, mam skojarzenia z planu modelu . Sprawie Stowarzyszenia jest:

User has_many Plans 
Plan belongs_to User 

W tym momencie mam również zasób dla modelu planowania, więc mogę pobrać wszystkie plany, pokazać konkretny plan i tak dalej. Ale chcę pójść dalej.

Chcę być w stanie zobaczyć plany konkretnego użytkownika i pozwolić konkretnemu użytkownikowi zobaczyć jego własne plany i edytować je.

Tak więc, na przykład, gdy idę do:

/Users/id/planuje

Chcę móc zobaczyć plany tego szczególności: ID użytkownika. Jeśli użytkownik, który odwiedza ten adres URL, jest zalogowany, chcę, aby mógł edytować te plany.

Jak mogę zarządzać wszystkimi tymi zachowaniami? Czy jest tam jakiś klejnot, który pomaga w tym? Czy muszę zrobić warunkowe w widokach mówiąc jeśli current_user ...

Odpowiedz

4

Zacznijmy tras można wykonywać swoje trasy tak:

resources :users do 
    resources :plans, only: [:index] 
end 

resources :plans, except: [:index] 

użyłem resources :plans wewnątrz resources :users mieć drogę jak to /users/:user_id/plans , podczas gdy resources :plans na zewnątrz jest dla reszty akcji (edytuj, niszcz, ...), które nie wymagają user_id, tj. plan jest identyfikowany przez unikalny identyfikator, więc nie potrzebujesz user_id, aby go pobrać z db do edycji lub niszczenia.

teraz na kontrolerze, możemy zrobić to tak:

class PlansController < ApplicationController 
    before_filter :is_plan_owner?, only: [:edit, :update] 

    def index 
    @plans = Plan.where(:user_id => params[:user_id]) 
    end 

    def edit 
    @plan = Plan.find(params[:id]) 
    end 

    private 

    def is_plan_owner? 
    if current_user != Plan.find(params[:id]).user 
     # Scream, shout, call 911 and/or redirect else where 
    end 
    end 
end 
4

To nie jest inaczej niż przy użyciu jakiegokolwiek innego zasobu zagnieżdżony. Wywołanie devise_for w pliku routes.rb nie zapewnia RESTful routingu dla modelu użytkownika. Pomyśl o tym bez zagnieżdżonego zasobu przez minutę, z tylko standardową instalacją Devise. Jeśli było rake routes co można uzyskać coś podobnego do poniższego:

new_user_session GET /users/sign_in(.:format)  devise/sessions#new 
     user_session POST /users/sign_in(.:format)  devise/sessions#create 
    user_password POST /users/password(.:format)  devise/passwords#create 
new_user_password GET /users/password/new(.:format) devise/passwords#new 
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit 
      sign_in GET /sign_in(.:format)    devise/sessions#new 

Zapewnia to nic do indeksowania lub wykazujących użytkowników, więc trzeba jeszcze dodać trasy dla że:

resources :users, only: [:index, :show] 

teraz ty otrzymujemy:

users GET /users(.:format)  users#index 
user GET /users/:id(.:format) users#show 

Ok, teraz jesteśmy już gdzieś, to jest to po prostu dodanie zasobu zagnieżdżonego, cały czas Devise płaci to nie umysł.

resources :users, only: [:index, :show] do 
    resources :plans 
end 

co daje routing pomysłowy chec

user_plans GET /users/:user_id/plans(.:format)   plans#index 
       POST /users/:user_id/plans(.:format)   plans#create 
new_user_plan GET /users/:user_id/plans/new(.:format)  plans#new 
edit_user_plan GET /users/:user_id/plans/:id/edit(.:format) plans#edit 
    user_plan GET /users/:user_id/plans/:id(.:format)  plans#show 
       PUT /users/:user_id/plans/:id(.:format)  plans#update 
      DELETE /users/:user_id/plans/:id(.:format)  plans#destroy 

I to naprawdę wszystko jest do niego. Dewiza nie wchodzi ci w drogę.

Powiązane problemy