【问题标题】:Rails 4: ActionController::UrlGenerationErrorRails 4:ActionController::UrlGenerationError
【发布时间】:2015-11-16 15:29:48
【问题描述】:

我有三个模型:

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/newhttp://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_controller 代码

标签: ruby-on-rails ruby-on-rails-4 has-many-through nested-resources nested-routes


【解决方案1】:

这里的问题是,你正在点击http://localhost:3000/users/1/calendars url,它映射到你的calendars#index 操作,正确的路径是: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 里面有它!

回答您的最后一个问题:

特别是,我不明白缺少的必需键:[:id, :user_id] 部分,因为我的 @user 和 @calendar 在我的 用户日历路径。

是的,您在控制器中定义了 @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

【讨论】:

  • 非常感谢您的详细回答。我应该如何更新我的calendars_controller 来解决问题?
  • 如果删除:` ` 来自index.html.erb 然后它将起作用
  • 基本上,这取决于你想要完成什么。您不能在 index.html.erb 中使用 user_calendar_path
  • 如果您告诉我您想在index 视图中显示,那么我可以告诉您要更改的内容。什么是可能的,什么不是。请说明你的目标。
  • 好吧,你不知道!这是show 页面的工作,您需要在show.html.erb 中包含这些行
【解决方案2】:

您尚未在 calendars#show 方法中设置 @user@calendarnew 动作可以很好地呈现您的视图,但它不知道如何填充参数 voor @user@calendar

【讨论】:

  • 感谢您的回复。我刚刚将@user = User.find(params[:user_id]) @calendar = @user.calendars.find(params[:calendar_id]) 添加到calendars#show,但问题和错误仍然出现。这段代码有问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-04
  • 2017-03-29
  • 2014-10-17
  • 2015-12-30
相关资源
最近更新 更多