Dar*_*use 4 ruby nested ruby-on-rails
背景
我正在我的应用程序中实现一项功能,允许用户评价和查看图片.
我的问题源于嵌套审查图片资源中的资源,特别是在我的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 />
Run Code Online (Sandbox Code Playgroud)
我在Stack Overflow.com上搜索了答案(我的参考文献在底部给出)并被建议这样做.
<td><%= link_to 'Edit', edit_picture_review_path(@picture, review) %></td>
Run Code Online (Sandbox Code Playgroud)
我遇到的每个解决方案都说要编辑包含特定对象的路径.如果这是任何迹象,它看起来确实应该工作.
参数
{"picture_id"=>"11",
"id"=>"4"}
Run Code Online (Sandbox Code Playgroud)
另外,我的path_url如下
http://localhost:3000/pictures/11/reviews/4/edit
Run Code Online (Sandbox Code Playgroud)
URL路径看起来与我定义的路径类似
edit_picture_review_path GET /pictures/:picture_id/reviews/:id/edit(.:format) reviews#edit
Run Code Online (Sandbox Code Playgroud)
我正在使用帖子/评论关系模型的图片/评论关系.
楷模
class Review < ActiveRecord::Base
belongs_to :picture
end
class Picture < ActiveRecord::Base
has_many :reviews
end
Run Code Online (Sandbox Code Playgroud)
在上面,我建立了图片和评论之间的一对多关系.
路线
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
Run Code Online (Sandbox Code Playgroud)
ReviewsController
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
Run Code Online (Sandbox Code Playgroud)
问题可能出在review_params上
post_id #should be
review_id
Run Code Online (Sandbox Code Playgroud)
评论#Index页面
<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 %>
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
评论#编辑页面
<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 %>
Run Code Online (Sandbox Code Playgroud)
的routes.rb
resources :pictures do
put :favorite, on: :member
resources :reviews
end
Run Code Online (Sandbox Code Playgroud)
如您所见,我使用的是嵌套资源.
参考和外部链接
缺少必需的键 ActionController :: UrlGenerationError缺少必需的键:[:id] 没有路由匹配缺少必需的键:[:id] ActionController :: UrlGenerationError:缺少必需的键:[:id] 没有路由匹配"缺少必需的键:[:id , :_ID]"
所有上述链接和更多咨询.每个解决方案都尝试过,这就是我重新开启这个问题的原因.我希望本指南可以作为前进这个问题的模板.
提前致谢.这不是一个简单的问题.祝好运.
一些观察,关闭袖口.
您的错误消息表明No route matches {:action=>"show", :controller=>"reviews".你的ReviewsController似乎错过了show动作,但这似乎并不相关.
所以这给我们留下了违规行:
<% form_for [:picture, @review] do |f| %>
请注意,您的错误不在此行:
<td><%= link_to 'Edit', edit_picture_review_path(@picture, review) %></td>
查看文档,在面向资源的样式下,我们可以看到以下指令:
例如,如果您的资源已定义关联,则您希望在给定路由设置正确的情况下向文档添加注释:
Run Code Online (Sandbox Code Playgroud)<%= form_for([@document, @comment]) do |f| %> ... <% end %>
对你而言,这意味着:
<% form_for [@picture, @review] do |f| %>
同一页也建议:
在刚刚显示的示例中,虽然没有明确指出,但我们仍然需要使用:url选项来指定表单的发送位置.但是,如果传递给form_for的记录是资源,则可以进一步简化,即它对应于一组RESTful路由,例如使用config/routes.rb中的resources方法定义.在这种情况下,Rails将简单地从记录本身推断出适当的URL
虽然你不应该需要它,但对你而言,这意味着:
<% form_for [@picture, @review], url: edit_picture_review_path(@picture, @review) do |f| %>
| 归档时间: |
|
| 查看次数: |
10516 次 |
| 最近记录: |