【问题标题】:Nesting in Rails嵌套在 Rails 中
【发布时间】:2016-10-06 03:07:22
【问题描述】:

我正在编写一个具有餐厅、菜单、类别和膳食模型的应用程序。如何在不嵌套超过 2 层的情况下实现这些?

class Restaurant < ActiveRecord::Base
  has_many :menus
  has_many :categories, through: :menus
  has_many :meals, through: :categories
end

class Menu < ActiveRecord::Base
  has_many :categories
  has_many :meals, through: :categories
end

class Category < ActiveRecord::Base
  has_many :meals
end

class Meal < ActiveRecord::Base
  belongs_to :category
end

我要的是如何编写路线。没有嵌套的链接看起来像:

restaurants GET      /restaurants(.:format)          restaurants#index
....
menus GET            /menus(.:format)                menus#index
....
categories GET       /categories(.:format)           categories#index
....

然后我将如何到达restaurants/1/menus/2/categories/3/meals/2?

【问题讨论】:

  • 如果你使用id作为url参数,那有什么问题呢?你可以使用/meals/2之类的路由。

标签: ruby-on-rails routes nested


【解决方案1】:

标准方法是不使用嵌套路由来访问项目。
正常路线

Rails.application.routes.draw do
  resources :restaurants
  resources :menus
  resources :meals
  resources :categories
end

你得到你需要的所有路线:

         Prefix Verb   URI Pattern                     Controller#Action
          menus GET    /menus(.:format)                menus#index
                POST   /menus(.:format)                menus#create
       new_menu GET    /menus/new(.:format)            menus#new
      edit_menu GET    /menus/:id/edit(.:format)       menus#edit
           menu GET    /menus/:id(.:format)            menus#show
                PATCH  /menus/:id(.:format)            menus#update
                PUT    /menus/:id(.:format)            menus#update
                DELETE /menus/:id(.:format)            menus#destroy
    restaurants GET    /restaurants(.:format)          restaurants#index
                POST   /restaurants(.:format)          restaurants#create
 new_restaurant GET    /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
          meals GET    /meals(.:format)                meals#index
                POST   /meals(.:format)                meals#create
       new_meal GET    /meals/new(.:format)            meals#new
      edit_meal GET    /meals/:id/edit(.:format)       meals#edit
           meal GET    /meals/:id(.:format)            meals#show
                PATCH  /meals/:id(.:format)            meals#update
                PUT    /meals/:id(.:format)            meals#update
                DELETE /meals/:id(.:format)            meals#destroy
     categories GET    /categories(.:format)           categories#index
                POST   /categories(.:format)           categories#create
   new_category GET    /categories/new(.:format)       categories#new
  edit_category GET    /categories/:id/edit(.:format)  categories#edit
       category GET    /categories/:id(.:format)       categories#show
                PATCH  /categories/:id(.:format)       categories#update
                PUT    /categories/:id(.:format)       categories#update
                DELETE /categories/:id(.:format)       categories#destroy

因此,如果您有@meal of restaurant#1 且 id:5,您可以通过

链接到它
<%= link_to @meal %>

并获取路径/meals/5

好的,按餐厅管理餐食会很方便(尤其是listnew)。
您可以为此添加嵌套路由:

Rails.application.routes.draw do
  resources :restaurants do
    resources :menus, only: [:index,:new]
  end
  resources :menus do
    resources :meals, only: [:index,:new]
  end
  resources :meals
  resources :categories
end

并获得一些新路线:

             Prefix Verb   URI Pattern                                     Controller#Action
   restaurant_menus GET    /restaurants/:restaurant_id/menus(.:format)     menus#index
new_restaurant_menu GET    /restaurants/:restaurant_id/menus/new(.:format) menus#new
   restaurant_meals GET    /restaurants/:restaurant_id/meals(.:format)     meals#index
new_restaurant_meal GET    /restaurants/:restaurant_id/meals/new(.:format) meals#new
...
         menu_meals GET    /menus/:menu_id/meals(.:format)                 meals#index
      new_menu_meal GET    /menus/:menu_id/meals/new(.:format)             meals#new

嵌套的深度永远不会超过 1。
现在您可以通过

链接到一家餐厅的所有餐点
<%= link_to 'All Meals', restaurant_meals(@restaurant) %>

以及菜单的所有餐点

<%= link_to 'All Meals', menu_meals(@menu) %>

如您所见,所有这些链接都调用meal#index,因此您的控制器必须处理不同的列表,即:

class MealsController < ApplicationController

  # GET /meals
  # GET /restaurants/:restaurant_id/meals
  # GET /menus/:menu_id/meals
  def index
    if params[:restaurant_id].present?
      @restaurant = Restaurant.find params[:restaurant_id]
      @meals = @restaurant.meals
    elsif params[:menu_id].present?
      @menu = Menu.find params[:menu_id]
      @meals = @menu.meals
    else
      @meals = Meal.all
    end
  end

end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多