RoR4:嵌套资源视图中的 NoMethodError
RoR4: NoMethodError in nested resources' view
我有一个带有嵌套资源设置的 parent/children 关系模型,以便从它的显示页面在某个父项下创建子数据。但是,当我从父页面 ("http://localhost:3000/brands/1/restaurants/new") 单击子页面的新页面 link 时,我收到一条错误消息 "NoMethodError in..."。请帮忙。
config/routes.rb
Rails.application.routes.draw do
resources :brands, shallow: true do
resources :restaurants
end
resources :managers
# Prefix Verb URI Pattern Controller#Action
# brand_restaurants GET /brands/:brand_id/restaurants(.:format) restaurants#index
# POST /brands/:brand_id/restaurants(.:format) restaurants#create
# new_brand_restaurant GET /brands/:brand_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
# brands GET /brands(.:format) brands#index
# POST /brands(.:format) brands#create
# new_brand GET /brands/new(.:format) brands#new
# edit_brand GET /brands/:id/edit(.:format) brands#edit
# brand GET /brands/:id(.:format) brands#show
# PATCH /brands/:id(.:format) brands#update
# PUT /brands/:id(.:format) brands#update
# DELETE /brands/:id(.:format) brands#destroy
# managers GET /managers(.:format) managers#index
# POST /managers(.:format) managers#create
# new_manager GET /managers/new(.:format) managers#new
# edit_manager GET /managers/:id/edit(.:format) managers#edit
# manager GET /managers/:id(.:format) managers#show
# PATCH /managers/:id(.:format) managers#update
# PUT /managers/:id(.:format) managers#update
# DELETE /managers/:id(.:format) managers#destroy managers#destroy
end
models/brand.rb
class Brand < ActiveRecord::Base
has_many :restaurants
end
models/restaurants.rb
class Restaurant < ActiveRecord::Base
belongs_to :brand
end
controllers/restaurants_controller.rb
class RestaurantsController < ApplicationController
before_action :set_restaurant, only: [:new, :create, :show, :edit, :update, :destroy]
# GET /restaurants
# GET /restaurants.json
def index
@restaurants = Restaurant.all
end
# GET /restaurants/1
# GET /restaurants/1.json
def show
end
# GET /restaurants/new
def new
# @restaurant = Restaurant.new
@restaurant = Restaurant.new
end
# GET /restaurants/1/edit
def edit
end
# POST /restaurants
# POST /restaurants.json
def create
@restaurant = Restaurant.new(restaurant_params)
respond_to do |format|
if @restaurant.save
format.html { redirect_to brands_path, notice: 'Restaurant was successfully created.' }
format.json { render :show, status: :created, location: @restaurant }
else
format.html { render :new }
format.json { render json: @restaurant.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /restaurants/1
# PATCH/PUT /restaurants/1.json
def update
respond_to do |format|
if @restaurant.update(restaurant_params)
format.html { redirect_to @restaurant, notice: 'Restaurant was successfully updated.' }
format.json { render :show, status: :ok, location: @restaurant }
else
format.html { render :edit }
format.json { render json: @restaurant.errors, status: :unprocessable_entity }
end
end
end
# DELETE /restaurants/1
# DELETE /restaurants/1.json
def destroy
@restaurant.destroy
respond_to do |format|
format.html { redirect_to restaurants_url, notice: 'Restaurant was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_restaurant
@restaurant = Restaurant.find_by(params[:brand_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def restaurant_params
params.require(:restaurant).permit(:name, :brand_id) if params[:restaurant]
end
end
views/brands/show.html
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @brand.name %>
</p>
<p>
<strong>Manager:</strong>
<%= @brand.manager_id %>
</p>
<table>
<% @brand.restaurants.each do |restaurant| %>
<tr>
<td><%= restaurant.name %></td>
<td><%= restaurant.brand_id %></td>
<td><%= link_to 'Show', restaurant %></td>
<td><%= link_to 'Edit', edit_restaurant_path(restaurant) %></td>
<td><%= link_to 'Destroy', restaurant, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br>
**<%= link_to 'Add New Restaurant', new_brand_restaurant_path(@brand) %>**
<%= link_to 'Edit', edit_brand_path(@brand) %> |
<%= link_to 'Back', brands_path %>
我做错了什么?
感谢您的帮助。
插件完整错误消息:
NoMethodError in Restaurants#new Showing
/Users/kaku/sample/relation/app/views/restaurants/_form.html.erb where
line #1 raised:
undefined method `restaurants_path' for
<#:0x007fd4ec2e46e0> Extracted source (around line #1): 1 2 3 4 5 6
<%= form_for(@restaurant) do |f| %>
<% if @restaurant.errors.any? %>
<%= pluralize(@restaurant.errors.count, "error") %> prohibited this restaurant from being saved:
Trace of template inclusion: app/views/restaurants/new.html.erb
Rails.root: /Users/kaku/sample/relation
Application Trace | Framework Trace | Full Trace
app/views/restaurants/_form.html.erb:1:in
_app_views_restaurants__form_html_erb__1732550980462972679_70276222510780' app/views/restaurants/new.html.erb:3:in
_app_views_restaurants_new_html_erb___209183791776779444_70276222559000'
Request
Parameters:
{"brand_id"=>"2"} Toggle session dump
_csrf_token: "MG3xNH+mscxxPiQqLVkF011BDb5RGlWJPuTN3GiEcGo=" session_id: "e1f92f37d231a058162af62bae976ff5" Toggle env dump
GATEWAY_INTERFACE: "CGI/1.1" HTTP_ACCEPT:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8"
HTTP_ACCEPT_ENCODING: "gzip, deflate, sdch" HTTP_ACCEPT_LANGUAGE:
"ja,en-US;q=0.8,en;q=0.6" REMOTE_ADDR: "::1" REMOTE_HOST: "::1"
SERVER_NAME: "localhost" SERVER_PROTOCOL: "HTTP/1.1" Response
Headers:
None
正如您在代码中指出的那样,我认为错误出在这一行
<%= link_to 'Add New Restaurant', new_brand_restaurant_path(@brand) %>
你应该在 restaurants_controller
的 new
方法中有 @brand
def new
@brand = Brand.find(params[:brand_id])
@restaurant = Restaurant.new
end
我还注意到您 set_restaurant
的定义有误。应该是
def set_restaurant
@restaurant = Restaurant.find(params[:id])
end
更新:
undefined method `restaurants_path'
你有嵌套的资源,所以这一行
<%= form_for(@restaurant) do |f| %>
应该是
<%= form_for [@brand, @restaurant] do |f| %>
我有一个带有嵌套资源设置的 parent/children 关系模型,以便从它的显示页面在某个父项下创建子数据。但是,当我从父页面 ("http://localhost:3000/brands/1/restaurants/new") 单击子页面的新页面 link 时,我收到一条错误消息 "NoMethodError in..."。请帮忙。
config/routes.rb
Rails.application.routes.draw do
resources :brands, shallow: true do
resources :restaurants
end
resources :managers
# Prefix Verb URI Pattern Controller#Action
# brand_restaurants GET /brands/:brand_id/restaurants(.:format) restaurants#index
# POST /brands/:brand_id/restaurants(.:format) restaurants#create
# new_brand_restaurant GET /brands/:brand_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
# brands GET /brands(.:format) brands#index
# POST /brands(.:format) brands#create
# new_brand GET /brands/new(.:format) brands#new
# edit_brand GET /brands/:id/edit(.:format) brands#edit
# brand GET /brands/:id(.:format) brands#show
# PATCH /brands/:id(.:format) brands#update
# PUT /brands/:id(.:format) brands#update
# DELETE /brands/:id(.:format) brands#destroy
# managers GET /managers(.:format) managers#index
# POST /managers(.:format) managers#create
# new_manager GET /managers/new(.:format) managers#new
# edit_manager GET /managers/:id/edit(.:format) managers#edit
# manager GET /managers/:id(.:format) managers#show
# PATCH /managers/:id(.:format) managers#update
# PUT /managers/:id(.:format) managers#update
# DELETE /managers/:id(.:format) managers#destroy managers#destroy
end
models/brand.rb
class Brand < ActiveRecord::Base
has_many :restaurants
end
models/restaurants.rb
class Restaurant < ActiveRecord::Base
belongs_to :brand
end
controllers/restaurants_controller.rb
class RestaurantsController < ApplicationController
before_action :set_restaurant, only: [:new, :create, :show, :edit, :update, :destroy]
# GET /restaurants
# GET /restaurants.json
def index
@restaurants = Restaurant.all
end
# GET /restaurants/1
# GET /restaurants/1.json
def show
end
# GET /restaurants/new
def new
# @restaurant = Restaurant.new
@restaurant = Restaurant.new
end
# GET /restaurants/1/edit
def edit
end
# POST /restaurants
# POST /restaurants.json
def create
@restaurant = Restaurant.new(restaurant_params)
respond_to do |format|
if @restaurant.save
format.html { redirect_to brands_path, notice: 'Restaurant was successfully created.' }
format.json { render :show, status: :created, location: @restaurant }
else
format.html { render :new }
format.json { render json: @restaurant.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /restaurants/1
# PATCH/PUT /restaurants/1.json
def update
respond_to do |format|
if @restaurant.update(restaurant_params)
format.html { redirect_to @restaurant, notice: 'Restaurant was successfully updated.' }
format.json { render :show, status: :ok, location: @restaurant }
else
format.html { render :edit }
format.json { render json: @restaurant.errors, status: :unprocessable_entity }
end
end
end
# DELETE /restaurants/1
# DELETE /restaurants/1.json
def destroy
@restaurant.destroy
respond_to do |format|
format.html { redirect_to restaurants_url, notice: 'Restaurant was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_restaurant
@restaurant = Restaurant.find_by(params[:brand_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def restaurant_params
params.require(:restaurant).permit(:name, :brand_id) if params[:restaurant]
end
end
views/brands/show.html
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @brand.name %>
</p>
<p>
<strong>Manager:</strong>
<%= @brand.manager_id %>
</p>
<table>
<% @brand.restaurants.each do |restaurant| %>
<tr>
<td><%= restaurant.name %></td>
<td><%= restaurant.brand_id %></td>
<td><%= link_to 'Show', restaurant %></td>
<td><%= link_to 'Edit', edit_restaurant_path(restaurant) %></td>
<td><%= link_to 'Destroy', restaurant, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br>
**<%= link_to 'Add New Restaurant', new_brand_restaurant_path(@brand) %>**
<%= link_to 'Edit', edit_brand_path(@brand) %> |
<%= link_to 'Back', brands_path %>
我做错了什么? 感谢您的帮助。
插件完整错误消息:
NoMethodError in Restaurants#new Showing /Users/kaku/sample/relation/app/views/restaurants/_form.html.erb where line #1 raised:
undefined method `restaurants_path' for
<#:0x007fd4ec2e46e0> Extracted source (around line #1): 1 2 3 4 5 6
<%= form_for(@restaurant) do |f| %>
<% if @restaurant.errors.any? %>
<%= pluralize(@restaurant.errors.count, "error") %> prohibited this restaurant from being saved:
Trace of template inclusion: app/views/restaurants/new.html.erb
Rails.root: /Users/kaku/sample/relation
Application Trace | Framework Trace | Full Trace app/views/restaurants/_form.html.erb:1:in
_app_views_restaurants__form_html_erb__1732550980462972679_70276222510780' app/views/restaurants/new.html.erb:3:in
_app_views_restaurants_new_html_erb___209183791776779444_70276222559000' RequestParameters:
{"brand_id"=>"2"} Toggle session dump _csrf_token: "MG3xNH+mscxxPiQqLVkF011BDb5RGlWJPuTN3GiEcGo=" session_id: "e1f92f37d231a058162af62bae976ff5" Toggle env dump GATEWAY_INTERFACE: "CGI/1.1" HTTP_ACCEPT: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8" HTTP_ACCEPT_ENCODING: "gzip, deflate, sdch" HTTP_ACCEPT_LANGUAGE: "ja,en-US;q=0.8,en;q=0.6" REMOTE_ADDR: "::1" REMOTE_HOST: "::1" SERVER_NAME: "localhost" SERVER_PROTOCOL: "HTTP/1.1" Response
Headers:
None
正如您在代码中指出的那样,我认为错误出在这一行
<%= link_to 'Add New Restaurant', new_brand_restaurant_path(@brand) %>
你应该在 restaurants_controller
new
方法中有 @brand
def new
@brand = Brand.find(params[:brand_id])
@restaurant = Restaurant.new
end
我还注意到您 set_restaurant
的定义有误。应该是
def set_restaurant
@restaurant = Restaurant.find(params[:id])
end
更新:
undefined method `restaurants_path'
你有嵌套的资源,所以这一行
<%= form_for(@restaurant) do |f| %>
应该是
<%= form_for [@brand, @restaurant] do |f| %>