Rails 4: ActionController::UrlGenerationError
Rails 4: ActionController::UrlGenerationError
我有三个模型:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
这是我的路线:
resources :users do
resources :administrations
resources :calendars
end
————————————
更新:
这是我在终端中 运行 rake routes
时得到的结果:
Prefix Verb URI Pattern Controller#Action
user_administrations GET /users/:user_id/administrations(.:format) administrations#index
POST /users/:user_id/administrations(.:format) administrations#create
new_user_administration GET /users/:user_id/administrations/new(.:format) administrations#new
edit_user_administration GET /users/:user_id/administrations/:id/edit(.:format) administrations#edit
user_administration GET /users/:user_id/administrations/:id(.:format) administrations#show
PATCH /users/:user_id/administrations/:id(.:format) administrations#update
PUT /users/:user_id/administrations/:id(.:format) administrations#update
DELETE /users/:user_id/administrations/:id(.:format) administrations#destroy
user_calendars GET /users/:user_id/calendars(.:format) calendars#index
POST /users/:user_id/calendars(.:format) calendars#create
new_user_calendar GET /users/:user_id/calendars/new(.:format) calendars#new
edit_user_calendar GET /users/:user_id/calendars/:id/edit(.:format) calendars#edit
user_calendar GET /users/:user_id/calendars/:id(.:format) calendars#show
PATCH /users/:user_id/calendars/:id(.:format) calendars#update
PUT /users/:user_id/calendars/:id(.:format) calendars#update
DELETE /users/:user_id/calendars/:id(.:format) calendars#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / static_pages#home
————————————
更新 2:
这是我的 calendars_controller.rb
文件:
class CalendarsController < ApplicationController
before_action :set_calendar, only: [:show, :edit, :update, :destroy]
# GET /calendars
# GET /calendars.json
def index
@calendars = Calendar.all
end
# GET /calendars/1
# GET /calendars/1.json
def show
end
# GET /calendars/new
def new
@user = User.find(params[:user_id])
@calendar = @user.calendars.new
end
# GET /calendars/1/edit
def edit
@user = User.find(params[:user_id])
@calendar = @user.calendar.find(params[:calendar_id])
end
# POST /calendars
# POST /calendars.json
def create
@user = User.find(params[:user_id])
@calendar = @user.calendars.new(calendar_params)
respond_to do |format|
if @calendar.save
format.html { redirect_to user_calendar_path(@user,@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /calendars/1
# PATCH/PUT /calendars/1.json
def update
respond_to do |format|
if @calendar.update(calendar_params)
format.html { redirect_to @calendar, notice: 'Calendar was successfully updated.' }
format.json { render :show, status: :ok, location: @calendar }
else
format.html { render :edit }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# DELETE /calendars/1
# DELETE /calendars/1.json
def destroy
@calendar.destroy
respond_to do |format|
format.html { redirect_to calendars_url, notice: 'Calendar was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_calendar
@calendar = Calendar.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def calendar_params
params.require(:calendar).permit(:name)
end
end
————————————
http://localhost:3000/users/1/calendars/new
和 http://localhost:3000/users/1/calendars/1
工作正常。
但是,每当我尝试访问 http://localhost:3000/users/1/calendars
时,我都会收到以下错误:
ActionController::UrlGenerationError in Calendars#index
Showing /Users/TXC/code/rails/calendy/app/views/calendars/index.html.erb where line #17 raised:
No route matches {:action=>"show", :controller=>"calendars", :id=>nil, :user_id=>nil} missing required keys: [:id, :user_id]
Extracted source (around line #17):
<tr>
<td><%= calendar.name %></td>
<td><%= link_to 'Show', user_calendar_path(@user, @calendar) %></td>
<td><%= link_to 'Edit', edit_user_calendar_path(@user, @calendar) %></td>
<td><%= link_to 'Destroy', calendar, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
特别是,我不理解 missing required keys: [:id, :user_id]
部分,因为我的 user_calendar_path
.
中同时包含 @user
和 @calendar
显然,我遗漏了一些东西,但我不知道是什么。
有什么想法吗?
您尚未在 calendars#show
方法中设置 @user
和 @calendar
。 new
操作可以很好地呈现您的视图,但它不知道如何填充 @user
和 @calendar
参数
这里的问题是,您正在点击映射到您的 calendars#index
操作的 http://localhost:3000/users/1/calendars
url,正确的路径是:user_calendars_path
并且它只需要一个参数 user_id
,因为它会将您带到用户的索引页面,并将显示数据库中的所有用户日历。
但是,在您的 index.html.erb
视图中,您有:
<td><%= link_to 'Edit', edit_user_calendar_path(@user, @calendar) %></td>
你不能拥有它,因为对于你控制器中的 index
操作,你没有设置 @user
和 @calendar
。您可以在 show.html.erb
中使用它,但不能在 index.html.erb
中使用。所以,这就是您收到此错误的原因。
简而言之,你不能在你的 index.html.erb
:
<td><%= link_to 'Show', user_calendar_path(@user, @calendar) %></td>
因为它被映射到 calendars#show
操作,相应的视图应该是 show.html.erb
但目前你在 index.html.erb
!
中有它
回答你最后一个问题:
In particular, I don't understand the missing required keys: [:id,
:user_id] part, since I have both @user and @calendar in my
user_calendar_path.
是的,您在控制器中定义了 @user
和 @calendar
,但是在 show
方法中并且 user_calendar_path
映射到 calendars#show
方法。但是,嘿!您是从对应于 calendars#index
操作的 index.html.erb
调用它的。那就是你所缺少的。希望现在一切都清楚了:-)
最后,区别很微妙。
user_calendars_path
用于 index
视图,显示特定用户的所有日历。在这种情况下,您必须在控制器的 index
操作中设置 @user
。
user_calendar_path
适用于 show
,它会将您带到特定用户的特定日历。在这种情况下,您必须在控制器的 show
方法中设置 @user
和 @calendar
。
我有三个模型:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
这是我的路线:
resources :users do
resources :administrations
resources :calendars
end
————————————
更新:
这是我在终端中 运行 rake routes
时得到的结果:
Prefix Verb URI Pattern Controller#Action
user_administrations GET /users/:user_id/administrations(.:format) administrations#index
POST /users/:user_id/administrations(.:format) administrations#create
new_user_administration GET /users/:user_id/administrations/new(.:format) administrations#new
edit_user_administration GET /users/:user_id/administrations/:id/edit(.:format) administrations#edit
user_administration GET /users/:user_id/administrations/:id(.:format) administrations#show
PATCH /users/:user_id/administrations/:id(.:format) administrations#update
PUT /users/:user_id/administrations/:id(.:format) administrations#update
DELETE /users/:user_id/administrations/:id(.:format) administrations#destroy
user_calendars GET /users/:user_id/calendars(.:format) calendars#index
POST /users/:user_id/calendars(.:format) calendars#create
new_user_calendar GET /users/:user_id/calendars/new(.:format) calendars#new
edit_user_calendar GET /users/:user_id/calendars/:id/edit(.:format) calendars#edit
user_calendar GET /users/:user_id/calendars/:id(.:format) calendars#show
PATCH /users/:user_id/calendars/:id(.:format) calendars#update
PUT /users/:user_id/calendars/:id(.:format) calendars#update
DELETE /users/:user_id/calendars/:id(.:format) calendars#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / static_pages#home
————————————
更新 2:
这是我的 calendars_controller.rb
文件:
class CalendarsController < ApplicationController
before_action :set_calendar, only: [:show, :edit, :update, :destroy]
# GET /calendars
# GET /calendars.json
def index
@calendars = Calendar.all
end
# GET /calendars/1
# GET /calendars/1.json
def show
end
# GET /calendars/new
def new
@user = User.find(params[:user_id])
@calendar = @user.calendars.new
end
# GET /calendars/1/edit
def edit
@user = User.find(params[:user_id])
@calendar = @user.calendar.find(params[:calendar_id])
end
# POST /calendars
# POST /calendars.json
def create
@user = User.find(params[:user_id])
@calendar = @user.calendars.new(calendar_params)
respond_to do |format|
if @calendar.save
format.html { redirect_to user_calendar_path(@user,@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /calendars/1
# PATCH/PUT /calendars/1.json
def update
respond_to do |format|
if @calendar.update(calendar_params)
format.html { redirect_to @calendar, notice: 'Calendar was successfully updated.' }
format.json { render :show, status: :ok, location: @calendar }
else
format.html { render :edit }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# DELETE /calendars/1
# DELETE /calendars/1.json
def destroy
@calendar.destroy
respond_to do |format|
format.html { redirect_to calendars_url, notice: 'Calendar was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_calendar
@calendar = Calendar.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def calendar_params
params.require(:calendar).permit(:name)
end
end
————————————
http://localhost:3000/users/1/calendars/new
和 http://localhost:3000/users/1/calendars/1
工作正常。
但是,每当我尝试访问 http://localhost:3000/users/1/calendars
时,我都会收到以下错误:
ActionController::UrlGenerationError in Calendars#index
Showing /Users/TXC/code/rails/calendy/app/views/calendars/index.html.erb where line #17 raised:
No route matches {:action=>"show", :controller=>"calendars", :id=>nil, :user_id=>nil} missing required keys: [:id, :user_id]
Extracted source (around line #17):
<tr>
<td><%= calendar.name %></td>
<td><%= link_to 'Show', user_calendar_path(@user, @calendar) %></td>
<td><%= link_to 'Edit', edit_user_calendar_path(@user, @calendar) %></td>
<td><%= link_to 'Destroy', calendar, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
特别是,我不理解 missing required keys: [:id, :user_id]
部分,因为我的 user_calendar_path
.
@user
和 @calendar
显然,我遗漏了一些东西,但我不知道是什么。
有什么想法吗?
您尚未在 calendars#show
方法中设置 @user
和 @calendar
。 new
操作可以很好地呈现您的视图,但它不知道如何填充 @user
和 @calendar
这里的问题是,您正在点击映射到您的 calendars#index
操作的 http://localhost:3000/users/1/calendars
url,正确的路径是:user_calendars_path
并且它只需要一个参数 user_id
,因为它会将您带到用户的索引页面,并将显示数据库中的所有用户日历。
但是,在您的 index.html.erb
视图中,您有:
<td><%= link_to 'Edit', edit_user_calendar_path(@user, @calendar) %></td>
你不能拥有它,因为对于你控制器中的 index
操作,你没有设置 @user
和 @calendar
。您可以在 show.html.erb
中使用它,但不能在 index.html.erb
中使用。所以,这就是您收到此错误的原因。
简而言之,你不能在你的 index.html.erb
:
<td><%= link_to 'Show', user_calendar_path(@user, @calendar) %></td>
因为它被映射到 calendars#show
操作,相应的视图应该是 show.html.erb
但目前你在 index.html.erb
!
回答你最后一个问题:
In particular, I don't understand the missing required keys: [:id, :user_id] part, since I have both @user and @calendar in my user_calendar_path.
是的,您在控制器中定义了 @user
和 @calendar
,但是在 show
方法中并且 user_calendar_path
映射到 calendars#show
方法。但是,嘿!您是从对应于 calendars#index
操作的 index.html.erb
调用它的。那就是你所缺少的。希望现在一切都清楚了:-)
最后,区别很微妙。
user_calendars_path
用于 index
视图,显示特定用户的所有日历。在这种情况下,您必须在控制器的 index
操作中设置 @user
。
user_calendar_path
适用于 show
,它会将您带到特定用户的特定日历。在这种情况下,您必须在控制器的 show
方法中设置 @user
和 @calendar
。