Rails 4:PostsController#edit中的ActiveRecord :: RecordNotFound

时间:2015-09-03 21:54:02

标签: ruby-on-rails ruby-on-rails-4 activerecord model-view-controller nested-resources

这是一个基本错误,很多人都提出类似的问题,例如:

然而,他们中没有一个能帮助我解决我现在面临的问题。

在我的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,我会显示属于此日历的所有帖子,ShowEdit和{{ 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 %>

知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

传递了一个命名路径(edit_post)的两个参数,它们需要一个参数。当控制器操作set_post在查找记录设置为:id时尝试确定要使用哪个@post时,这会导致问题。

这也是为什么你将.5神秘地附加到网址末尾的原因 - 我相信5:id的{​​{1}}(在此上下文),post11的{​​{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)