【问题标题】:No route matches - missing required keys[:id]没有路线匹配 - 缺少必需的键[:id]
【发布时间】:2014-10-07 15:50:55
【问题描述】:

背景

我正在我的应用程序中实现一项功能,该功能允许用户对图片进行评分和评论。

我的问题源于将评论资源嵌套在图片资源中,特别是在我的 Review#Edit 函数中。错误消息特别声明缺少必需的键:[:id]

错误信息

ActionController::URLGenerationError in Reviews#Edit
No route matches {:action=>"show", :controller=>"reviews", :format=>nil, :picture_id=>#<Review id: 4, username: "DarkMouse", body: "Updating review", picture_id: 11, created_at: "2014-08-14 03:26:52", updated_at: "2014-08-14 03:55:29">, :id=>nil} missing required keys: [:id]
Undefined method 'reviews_path' for #<#<Class:0x45c1b00>:0x39ae810>
Extracted source (Around line #7):
4 <div class = 'center'>
5   <div class = 'center'>
6 
7     <% form_for [:picture, @review] do |f| %>
8
9      <p>
10        <%= f.label :username, :class => 'marker' %><br /> 

我在 Stack Overflow.com 上搜索了答案(我的参考资料在底部给出)并被建议这样做。

<td><%= link_to 'Edit', edit_picture_review_path(@picture, review) %></td>

我遇到的每个解决方案都说要编辑路径以包含特定对象。如果这是任何迹象,它看起来确实应该有效。

参数

{"picture_id"=>"11",
"id"=>"4"}

另外,我的path_url如下

http://localhost:3000/pictures/11/reviews/4/edit

URL 路径看起来也与我定义的路由相似

edit_picture_review_path GET   /pictures/:picture_id/reviews/:id/edit(.:format) reviews#edit

我正在为图片/评论关系使用帖子/评论关系模型。

模型

class Review < ActiveRecord::Base
  belongs_to :picture
end

class Picture < ActiveRecord::Base
  has_many :reviews
end

以上,我在图片和评论之间建立了一对多的关系。

路线

favorite_picture_path    PUT   /pictures/:id/favorite(.:format)     pictures#favorite
picture_reviews_pat      GET   /pictures/:picture_id/reviews(.:format)  reviews#index
                         POST  /pictures/:picture_id/reviews(.:format)  reviews#create
new_picture_review_path  GET   /pictures/:picture_id/reviews/new(.:format)  reviews#new
edit_picture_review_path GET   /pictures/:picture_id/reviews/:id/edit(.:format) reviews#edit
pictures_review_path     GET   /pictures/:picture_id/reviews/:id(.:format)  reviews#show
                        PATCH  /pictures/:picture_id/reviews/:id(.:format)  reviews#update
                        PUT    /pictures/:picture_id/reviews/:id(.:format)  reviews#update
                        DELETE /pictures/:picture_id/reviews/:id(.:format)  reviews#destroy

评论控制器

class ReviewsController < ApplicationController
  before_action :set_review, only: [:show, :edit, :update, :destroy]
  before_filter :find_picture, only: [:index, :create, :edit, :update, :destroy]


  def edit
     @review = Review.find(params[:id])
  end

  def update
    @review = Review.find(params[:id])

    if @review.update_attributes(params[:review])
      flash[:notice] = "Review updated"
      redirect_to @picture
    else
      flash[:error] = "There was an error updating your review"
      redirect_to @picture
    end
  end

  private

    def set_review
      @review = Review.find(params[:id])
    end

   def find_picture
     @picture = Picture.find(params[:picture_id])
   end

    def review_params
      params.require(:review).permit(:username, :body, :post_id)
    end
end

问题可能出在 review_params

post_id #should be
review_id

评论#索引页面

<h3>Reviews for <%= "#{@picture.title}" %></h3>

<table class = "reviews-table">
  <thead>
    <tr>
      <th>Review</th>
      <th>Username</th>
      <th><th>
    </tr>
  </thead>

<tbody>
  <% @picture.reviews.each do |review| %>

    <tr>
      <td><%= review.body %></td>
      <td><%= review.username %></td>
      <td><%= link_to 'Edit', edit_picture_review_path(@picture, review) %></td>
</tr>

<% end %>

<div class = 'center'>
  <p><%= link_to 'New Review', new_reviews_path(@review), :class => "btn btn-info" %></p>
  <p><%= link_to 'Back', picture_path, :class => "btn btn-info" %></p>
</div>

评论#编辑页面

<h3>Edit Review</h3>

<div class = 'center'>

<div class = 'center'>

<%= form_for [:picture, @review] do |f| %>

  <p>
    <%= f.label :username, :class => 'marker' %><br />
    <%= f.text_field :username %>
  </p>

  <p>
    <%= f.label :body, "Review", :class => 'marker' %><br />
    <%= f.text_area :body, :rows => "10", :cols => "10" %>
  </p>

  <p>
    <%= f.submit "Submit Review", :class => 'btn btn-success' %>
  </p>

<% end %>

routes.rb

resources :pictures do
  put :favorite, on: :member
  resources :reviews
end

正如你在上面看到的,我使用的是嵌套资源。

参考和外部链接

Missing required keys ActionController::UrlGenerationError missing required keys: [:id] No route matches missing required keys: [:id] ActionController::UrlGenerationError: missing required keys: [:id] No routes matches "missing required keys: [:id, :_id]"

以上所有链接和更多咨询。每种解决方案都尝试过,但都没有奏效。这就是我重新打开这个问题的原因。我希望本指南可以作为解决这个问题的模板。

提前致谢。这不是一个容易的问题。祝你好运。

【问题讨论】:

    标签: ruby-on-rails ruby nested


    【解决方案1】:

    一些观察,即兴发挥。

    您的错误消息表明No route matches {:action=&gt;"show", :controller=&gt;"reviews"。 您的 ReviewController 似乎确实缺少显示操作,但这似乎不相关。

    所以这给我们留下了违规的行:

    &lt;% form_for [:picture, @review] do |f| %&gt;

    注意,你的错误不在这一行:

    &lt;td&gt;&lt;%= link_to 'Edit', edit_picture_review_path(@picture, review) %&gt;&lt;/td&gt;

    查看docs,在Resource-oriented style下,我们可以看到如下指令:

    如果您的资源定义了关联,例如,您希望 鉴于路由设置正确,将 cmets 添加到文档中:

    <%= form_for([@document, @comment]) do |f| %>
     ...
    <% end %>
    

    对你来说,这意味着:

    &lt;% form_for [@picture, @review] do |f| %&gt;

    同一页面还建议:

    在刚刚显示的示例中,虽然没有明确指出,但我们 仍然需要使用 :url 选项来指定表单的位置 将被发送。但是,如果进一步简化是可能的 传递给 form_for 的记录是一个资源,即它对应于一个 一组 RESTful 路由,例如使用资源方法定义 配置/路由.rb。在这种情况下,Rails 将简单地推断出适当的 记录本身的 URL

    虽然你不应该需要它,但对你来说,这意味着:

    &lt;% form_for [@picture, @review], url: edit_picture_review_path(@picture, @review) do |f| %&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-09
      • 1970-01-01
      • 2017-07-22
      相关资源
      最近更新 更多