2017-04-15 20 views
1

提交我的新餐廳的形式時,我得到了以下錯誤: 沒有路由匹配[POST]「/餐廳」沒有POST路線 - 嵌套資源造成混亂

而且沒有[POST]路徑當我運行耙路線。我得到如下:

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 

我的routes.rb:

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

我user.rb:

has_many :reviews 
has_many :restaurants 

我restaurant.rb:

has_many :reviews 
belongs_to :category 
belongs_to :user 

我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  

我的餐館/ new.html.erb:

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

有沒有更好的方式來餐廳綁在用戶爲了讓餐館老闆到編輯頁面?如果沒有,我會如何解決這個錯誤?

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

回答

0

嘗試在表單中的更改此:

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

你可以在這裏讀到它http://guides.rubyonrails.org/form_helpers.html#relying-on-record-identification

+0

那固定的路由錯誤,現在我得到 「無法找到用戶與 'ID'=」 運行時set_user。我使用指向創建餐廳頁面的鏈接更新了帖子。 –

+0

這個錯誤提高了#create動作的權利?這是因爲你不應該在那裏執行它,因爲你正在執行'current_user.restaurants.build(restaurant_params)',所以沒有意義。你應該把你的回調改成這個'before_action:set_user,除了::create'並且在你的創建操作中刪除'@restaurant.user = @ user' –

+0

感謝你的幫助!這讓它工作。我還必須將set_user中的代碼更改爲@user = current_user。 –

1

你濫用嵌套。嵌套路線時,您應該只嵌套一層深度:

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

resources :users do 
    # ... 
end 

嵌套應用於上下文 - 而不是認證/授權。

雖然您可以將restaurants的創建動作嵌套在用戶POST /users/:user_id/restaurants下,但只有在您爲其他用戶創建餐廳時纔有意義。

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 

這大大降低了複雜度。如果你想創建嵌套的路線,以顯示用戶的餐館或評論一個非常強大的模式是使用模塊:

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 

這讓我們使用根據上下文不同的控制器。用戶評論與所有評論完全不同。

當涉及到爲餐廳創建評論時,您將希望使用嵌套,因爲路徑提供了重要的上下文。

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

真棒迴應,謝謝!這爲我清除了很多;我不知道如果沒有嵌套,你可以做很多事情。真的很感激它。 –