2017-04-15 1 views
1

je reçois l'erreur suivante lors de la présentation de mon nouveau formulaire restaurant: Aucun résultat de route [POST] «/restaurants »Aucun itinéraire POST - ressources imbriquées provoquant la confusion

Et il n'y a pas de chemin [POST] quand je lance rake routes. Je reçois le texte suivant:

user_restaurants GET /users/:user_id/restaurants(.:format)    restaurants#index 
         POST /users/:user_id/restaurants(.:format)    restaurants#create 
    new_user_restaurant GET /users/:user_id/restaurants/new(.:format)   restaurants#new 
     edit_restaurant GET /restaurants/:id/edit(.:format)     restaurants#edit 
       restaurant GET /restaurants/:id(.:format)      restaurants#show 
         PATCH /restaurants/:id(.:format)      restaurants#update 
         PUT /restaurants/:id(.:format)      restaurants#update 
         DELETE /restaurants/:id(.:format)      restaurants#destroy 

Mon routes.rb:

devise_for :users 
resources :users, :shallow => true do 
    resources :restaurants do 
    resources :reviews, except: [:index, :show] #create review paths 
    end 
end 

Mon user.rb:

has_many :reviews 
has_many :restaurants 

Mon restaurant.rb:

has_many :reviews 
belongs_to :category 
belongs_to :user 

Mon restaurants_controller .rb:

before_action :set_user 
before_action :authenticate_user!, only: [:create, :new, :edit, :update, 
:destroy] 
before_action :check_if_owner?, only: [:edit, :update, :destroy] 

def new 
    @restaurant = Restaurant.new(user: @user) #create a new restaurant 
end 

def create 
    @restaurant = current_user.restaurants.build(restaurant_params) 
    @restaurant.user = @user 
    @restaurant.save 
    redirect_to @restaurant 
end 

private 
    def set_user 
    @user = User.find(params[:user_id]) 
    end 

    def restaurant_params 
    params.require(:restaurant).permit(:name, :description, :category_id, 
    :address1, :address2, :city, :state, :zipcode, :phone, :email, :image, 
    :user_id) 
    end  

Mes restaurants/new.html.erb:

<%= form_for @restaurant do |f| %> 

Y at-il une meilleure façon de lier un restaurant à un utilisateur afin de permettre à un propriétaire de restaurant à modifier leur page? Si non, comment pourrais-je réparer l'erreur?

<%= link_to "Create a Restaurant", 
new_user_restaurant_path(current_user.id), class: "btn btn-lg btn-primary"%> 

Répondre

0

Essayez de changer dans votre formulaire:

<%= form_for [@user, @restaurant] do |f| %>

Vous pouvez lire ici http://guides.rubyonrails.org/form_helpers.html#relying-on-record-identification

+0

Ce fixe l'erreur de routage, maintenant je reçois "Impossible de trouver l'utilisateur 'id' =" lors de l'exécution SET_USER. J'ai mis à jour le post avec le lien vers la page de création de restaurant. –

+0

Cette erreur se lève sur #create action right? C'est parce que vous ne devriez pas l'exécuter ici, n'a pas de sens puisque vous faites 'current_user.restaurants.build (restaurant_params)'. Vous devriez changer votre callback pour ce 'before_action: set_user, sauf:: create' et dans votre action create supprimer '@restaurant.user = @ user' –

+0

Merci pour l'aide! Cela a fonctionné. J'ai aussi dû changer le code dans set_user en @user = current_user. –

1

Vous abusant de la nidification. Lorsque l'imbrication des itinéraires que vous ne devriez jamais nid d'un niveau profond:

resources :restaurants, shallow: true do 
    resources :reviews 
end 

resources :users do 
    # ... 
end 

Et imbrication doit être utilisé pour le contexte - pas d'authentification/autorisation.

Et bien que vous puissiez imbriquer l'action de création pour restaurants sous les utilisateurs POST /users/:user_id/restaurants n'a de sens que si vous créez un restaurant pour d'autres utilisateurs.

class RestaurantsController 

    before_action :authenticate_user!, only: [:create, :new, :edit, :update, 
:destroy] 
    before_action :check_if_owner?, only: [:edit, :update, :destroy] 

    # POST /restaurants 
    def create 
    @restaurant = current_user.restaurants.new(restaurant_params) 

    # ... 
    end 
end 

Cela réduit considérablement le niveau de complexité. Si vous voulez créer des itinéraires imbriqués pour montrer les utilisateurs restaurants ou commentaires un modèle très puissant est d'utiliser des modules:

resources :reviews, except: [:new, :create] 

resources :users do 
    resources :reviews, only: [:index], module: :users 
end 

# app/controllers/reviews_controller.rb 
class ReviewsController < ApplicationController 
    # ... 

    # GET /reviews 
    def index 
    @reviews = Review.all 
    end 
end 

# app/controllers/users/reviews_controller.rb 
class Users::ReviewsController < ApplicationController 
    # GET /users/:user_id/reviews 
    def index 
    @user = User.includes(:reviews).find(params[:user_id]) 
    @reviews = @user.reviews 
    end 
end 

Cela nous permet d'utiliser différents contrôleurs en fonction du contexte. Un avis des utilisateurs est une ressource très différente de toutes les critiques.

Lorsqu'il s'agit de créer des critiques pour un restaurant, vous voudrez utiliser l'imbrication car le chemin fournit un contexte vital.

resources :restaurants do 
    resources :reviews, only: [:new, :create, :index], module: :users 
end 


# app/controllers/restaurants/reviews_controller.rb 
class Restaurants::ReviewsController 

    # GET /restaurants/:restaurant_id/reviews/new 
    def new 
    @restaurant = Restaurant.find(params[:Restaurant_id]) 
    @review = @restaurant.review.new 
    end 

    # POST /restaurants/:restaurant_id/reviews 
    def create 
    @restaurant = Restaurant.find(params[:Restaurant_id]) 
    @review = @restaurant.review.new(review_params) do |r| 
     r.user = current_user 
    end 
    # ... 
    end 

    # GET /restaurants/:restaurant_id/reviews 
    def index 
    @restaurant = Restaurant.includes(:reviews).find(params[:Restaurant_id]) 
    @reviews = @restaurant.reviews 
    end 
end 

# app/views/reviews/_form.html.erb 
<%= form_for(resource) do %> 
    # ... 
<% end %> 

# app/views/restaurants/reviews/new.html.erb 
<%= render partial: 'reviews/form', resource: [@review.restaurant, @review] %> 

# app/views/reviews/edit.html.erb 
<%= render partial: 'reviews/form', resource: @review %> 
+0

Réponse impressionnante, merci! Cela éclaircit beaucoup pour moi; Je n'avais aucune idée que tu pouvais faire autant sans nicher. J'apprécie beaucoup. –