recursos rails formularios anidados ruby-on-rails devise associations crud

ruby-on-rails - anidados - rails formularios



Confundido sobre los recursos anidados y la autenticación en Rails (2)

Comencemos por las rutas, puedes hacer tus rutas así:

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

Usé resources :plans dentro de resources :users tienen una ruta como esta /users/:user_id/plans , mientras que los resources :plans externos son para el resto de las acciones (editar, destruir, ...) que no requieren una user_id , es decir, un plan se identifica con una identificación única, por lo que no necesita un user_id para buscarlo desde la base de datos para editarlo o destruirlo.

Ahora para el controlador, podemos hacerlo así:

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

Veamos si puedo explicarme lo suficiente sobre las dudas que tengo.

Tengo un modelo de usuario administrado por Devise. Entonces en mis rutas tengo:

devise_for :users

En el modelo de Usuario , tengo una asociación con el modelo de Plan . La asociación es:

User has_many Plans Plan belongs_to User

En este punto, también tengo un recurso para el modelo del Plan, por lo que puedo buscar todos los Planes, mostrar un plan particular, etc. Pero quiero ir más allá.

Quiero poder ver los planes de un Usuario en particular y permitir que un Usuario en particular vea sus propios planes y los edite.

Entonces, por ejemplo, cada vez que voy a:

/ users /: id / planes

Quiero poder ver los planes para ese particular: usuario de id. Y si el usuario que está visitando esa url es el que está conectado, quiero que él pueda editar esos planes.

¿Cómo puedo gestionar todo este comportamiento? ¿Hay alguna joya que ayuda con eso? O necesito hacer condicionales en las vistas diciendo si current_user ...


Esto no es diferente a usar cualquier otro recurso anidado. La llamada a devise_for en el archivo routes.rb no proporciona enrutamiento RESTful al modelo de usuario. Piénselo sin el recurso anidado durante un minuto, con solo una instalación estándar de Devise. Si tuviera que rake routes , obtendría algo similar a lo siguiente:

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

Esto no proporciona nada para indexar o mostrar usuarios, por lo que aún necesitaría agregar rutas para eso:

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

Ahora obtienes:

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

Bien, ahora estamos llegando a algún lado, entonces simplemente está agregando el recurso anidado, todo el tiempo a Devise no le importa.

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

Lo que te da el enrutamiento ingenioso que deseas

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

Y eso es todo lo que hay que hacer. Devise se mantiene fuera de tu camino en este caso.