这是一个基本错误,很多人都提出类似的问题,例如:
然而,他们中没有一个能帮助我解决我现在面临的问题。
在我的Rails 4应用程序中,我有四个模型:
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
has_many: :posts
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
以下是我的路线:
Rails.application.routes.draw do
root to: 'pages#home'
devise_for :users, :path => 'account'
resources :calendars do
resources :posts, shallow: true
end
end
问题在于:当我在日历上时,例如http://localhost:3000/calendars/11
,我会显示属于此日历的所有帖子,Show
,Edit
和{{ 1}}链接每个帖子。
当我点击Destroy
链接时,我被带到Edit
*,我收到以下错误:
http://localhost:3000/posts/11/edit.5
注意:我不知道为什么我会一直得到这个奇怪的网址,最后是ActiveRecord::RecordNotFound in PostsController#edit
Couldn't find Post with 'id'=11
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
。
以下是我.5
的内容:
PostsController
更新:根据@ Nathan的评论,这里是class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
@posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
@post = Post.new
end
# GET /posts/1/edit
def edit
@calendar = Calendar.find(params[:calendar_id])
end
# POST /posts
# POST /posts.json
def create
@calendar = Calendar.find(params[:calendar_id])
@post = @calendar.posts.create(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to calendar_path(@calendar), notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: @post }
else
format.html { render :new }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
@calendar = Calendar.find(params[:calendar_id])
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to calendar_path(@calendar), notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: @post }
else
format.html { render :edit }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
@calendar = Calendar.find(params[:calendar_id])
@post.destroy
respond_to do |format|
format.html { redirect_to calendar_path(@calendar), notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:date, :time, :subject, :format, :copy, :media)
end
end
视图:
edit.html.erb
以下是其中使用的<h1>Editing Post</h1>
<%= render 'form' %>
<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
部分:
_form.html.erb
更新2 :根据@ danielricecodes&#39;回答,这是在终端中运行<%= form_for(@post) do |f| %>
<% if @post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% @post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<p>
<%= f.label :date %><br>
<%= f.date_select :date %>
</p>
<p>
<%= f.label :time %><br>
<%= f.time_select :time %>
</p>
<p>
<%= f.label :subject %><br>
<%= f.text_field :subject %>
</p>
<p>
<%= f.label :format %><br>
<%= f.text_field :format %>
</p>
<p>
<%= f.label :copy %><br>
<%= f.text_area :copy %>
</p>
<p>
<%= f.label :media %><br>
<%= f.text_field :media %>
</p>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
的结果:
rake routes
更新3 :根据@ Nathan的第二条评论,以下是我的Prefix Verb URI Pattern Controller#Action
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
root GET / pages#home
new_user_session GET /account/sign_in(.:format) devise/sessions#new
user_session POST /account/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /account/sign_out(.:format) devise/sessions#destroy
user_password POST /account/password(.:format) devise/passwords#create
new_user_password GET /account/password/new(.:format) devise/passwords#new
edit_user_password GET /account/password/edit(.:format) devise/passwords#edit
PATCH /account/password(.:format) devise/passwords#update
PUT /account/password(.:format) devise/passwords#update
cancel_user_registration GET /account/cancel(.:format) devise/registrations#cancel
user_registration POST /account(.:format) devise/registrations#create
new_user_registration GET /account/sign_up(.:format) devise/registrations#new
edit_user_registration GET /account/edit(.:format) devise/registrations#edit
PATCH /account(.:format) devise/registrations#update
PUT /account(.:format) devise/registrations#update
DELETE /account(.:format) devise/registrations#destroy
user_confirmation POST /account/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /account/confirmation/new(.:format) devise/confirmations#new
GET /account/confirmation(.:format) devise/confirmations#show
user_unlock POST /account/unlock(.:format) devise/unlocks#create
new_user_unlock GET /account/unlock/new(.:format) devise/unlocks#new
GET /account/unlock(.:format) devise/unlocks#show
calendar_posts GET /calendars/:calendar_id/posts(.:format) posts#index
POST /calendars/:calendar_id/posts(.:format) posts#create
new_calendar_post GET /calendars/:calendar_id/posts/new(.:format) posts#new
GET /posts/:id/edit(.:format) posts#edit
GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
calendars GET /calendars(.:format) calendars#index
POST /calendars(.:format) calendars#create
new_calendar GET /calendars/new(.:format) calendars#new
edit_calendar GET /calendars/:id/edit(.:format) calendars#edit
calendar GET /calendars/:id(.:format) calendars#show
PATCH /calendars/:id(.:format) calendars#update
PUT /calendars/:id(.:format) calendars#update
DELETE /calendars/:id(.:format) calendars#destroy
日历视图的内容:
show.html.erb
更新4 :以下是从帖子资源中删除浅层选项时的路由:
<h2><%= @calendar.name %> Calendar</h2>
<h3>Posts</h3>
<% if @calendar.posts.any? %>
<table>
<tr>
<th>Date</th>
<th>Time</th>
<th>Subject</th>
<th>Format</th>
<th>Copy</th>
<th>Media</th>
</tr>
<% @calendar.posts.each do |post| %>
<tr>
<td><%= post.date %></td>
<td><%= post.time %></td>
<td><%= post.subject %></td>
<td><%= post.format %></td>
<td><%= post.copy %></td>
<td><%= post.media %></td>
<td><%= link_to 'View', post %></td>
<td><%= link_to 'Update', edit_post_path(@calendar, post) %></td>
<td><%= link_to 'Delete', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
</table>
<% end %>
<% else %>
<p>This calendar does not contain any post yet: just create one with the form below.</p>
<% end %>
<h3>Add a post to <%= @calendar.name %> Calendar:</h3>
<%= form_for([@calendar, @calendar.posts.build]) do |f| %>
<p>
<%= f.label :date %><br>
<%= f.date_select :date %>
</p>
<p>
<%= f.label :time %><br>
<%= f.time_select :time %>
</p>
<p>
<%= f.label :subject %><br>
<%= f.text_field :subject %>
</p>
<p>
<%= f.label :format %><br>
<%= f.text_field :format %>
</p>
<p>
<%= f.label :copy %><br>
<%= f.text_area :copy %>
</p>
<p>
<%= f.label :media %><br>
<%= f.text_field :media %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Edit', edit_calendar_path %> |
<%= link_to 'Back', calendars_path %>
知道如何解决这个问题吗?
答案 0 :(得分:1)
传递了一个命名路径(edit_post
)的两个参数,它们需要一个参数。当控制器操作set_post
在查找记录设置为:id
时尝试确定要使用哪个@post
时,这会导致问题。
这也是为什么你将.5
神秘地附加到网址末尾的原因 - 我相信5
是:id
的{{1}}(在此上下文),post
是11
的{{1}}。
:id
只需知道您要修改的帖子的@calendar
,因此您可以通过将edit_post_path
更改为:id
来解决此问题(请注意删除<%= link_to 'Update', edit_post_path(@calendar, post) %>
)。
如果确实希望将此帖子编辑为嵌套在日历下的资源(位于路径<%= link_to 'Update', edit_post_path(post) %>
),请查看您的@calendar
。 /calendars/<calendar_id>/posts/<post_id>/edit
选项(在config/routes.rb
下嵌套shallow: true
时使用)是保留嵌套:posts
路径的原因。
您需要拥有嵌套的:calendars
路径,然后您可以像现在一样传递两个参数(类似:edit
)。
答案 1 :(得分:0)
错误让我觉得您在视图模板中构建的链接存在问题。我提供了更多帮助,但我看不到View文件或rake routes
的输出。没有这两件事,我很难告诉你为什么你的应用程序生成一个有趣的网址 - 但这通常意味着视图模板没有调用正确的url_helper。
答案 2 :(得分:0)
他与edit_post_path
相关的问题。使用浅嵌套时,编辑路径位于父范围之外。 .5
是添加到网址的帖子ID,但不是有效的网址参数,因为日历中已经存在ID参数。根据您的路由设置方式,看起来您需要将ID设置为链接中的参数,如下所示:
link_to "edit post", edit_post_path(post)