2012-12-30 17 views
5

Vediamo se riesco a spiegarmi abbastanza bene i dubbi che ho.Confuso circa le risorse nidificate e l'autenticazione in Rails

Possiedo un modello Utente gestito da Devise. Così nelle mie vie che ho:

devise_for :users 

Nel modello utente, ho un'associazione con il modello Piano. L'assocation è:

User has_many Plans 
Plan belongs_to User 

A questo punto ho anche una risorsa per il modello di piano, così posso recuperare tutti i piani, mostrano un particolare piano e così via. Ma voglio andare oltre.

Desidero poter vedere i piani di un particolare utente e consentire a un particolare utente di visualizzare i propri piani e modificarli.

Così, per esempio, ogni volta che vado a:

/utenti /: id/piani

Voglio essere in grado di vedere i piani per quel particolare: id utente. E se l'utente che sta visitando quell'URL è quello che ha effettuato l'accesso, voglio che sia in grado di modificare quei piani.

Come posso gestire tutto questo comportamento? C'è qualche gemma là fuori che ti aiuta? O ho bisogno di fare condizionali nelle viste dicendo che se current_user ...

risposta

4

Cominciamo con percorsi, è possibile rendere i percorsi come questo:

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

resources :plans, except: [:index] 

Ho usato resources :plans all'interno resources :users avere percorso come questo /users/:user_id/plans , mentre il resources :plans esterno è per il resto delle azioni (modifica, distruggi, ...) che non richiedono un user_id, cioè, un piano è identificato da un id univoco quindi non è necessario un user_id per recuperarlo dal db per la modifica o la distruzione.

Ora per il controller, possiamo fare in questo modo:

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

questo non è diverso rispetto all'utilizzo di qualsiasi altra risorsa nidificato. La chiamata a devise_for nel file routes.rb non fornisce il routing RESTful al modello utente. Pensaci senza la risorsa nidificata per un minuto, con solo un'installazione Devise standard. Se si dovesse rake routes si otterrebbe qualcosa di simile al seguente:

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 

Questo prevede nulla per indicizzazione o che mostrano gli utenti, in modo che avrebbe ancora bisogno di aggiungere percorsi per questo:

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

Ora get:

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

Ok, ora stiamo ottenendo da qualche parte, allora è semplicemente aggiungendo la risorsa nidificato, per tutto il tempo Devise paga che nessuna mente.

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

che vi dà l'instradamento di risorse che si desiderano

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 

E questo è davvero tutto quello che c'è ad esso. Devise ti toglie di mezzo questo.

Problemi correlati