未定义的方法或我的Active Record错误

对不起,如果我的问题很愚蠢,但Rails对我来说是新的。 我制作了两个型号和两个控制器。 在我制作了第二个模型并添加了第一个模型后,我的问题就开始了。

class SentencesController < ApplicationController before_action :find_story def create @sentence = find_story.sentences.build(sentence_params) if @sentence.save flash[:success] = "You wrote the continuation!" render 'stories/show' else render 'stories/show' end end private def sentence_params params.require(:sentence).permit(:content) end def find_story @story = Story.find(params[:id]) end end 

还有这个:

 class StoriesController < ApplicationController ........ def show @story = Story.find(params[:id]) @sentence = @story.sentences.build end ......... end 

我在定义实例变量@story = Story.find(params [:id])时遇到问题。 错误:SentencesController #create中的ActiveRecord :: RecordNotFound。 我尝试过很多种组合。

这是我的迁移文件:

 class CreateStories < ActiveRecord::Migration[5.1] def change create_table :stories do |t| t.string :title t.text :content t.timestamps end end end class CreateSentences < ActiveRecord::Migration[5.1] def change create_table :sentences do |t| t.text :content t.references :story, foreign_key: true t.timestamps end add_index :sentences, [:story_id, :created_at] end end 

我做错了什么?

编辑(路线):

 Rails.application.routes.draw do root 'stories#index' get 'stories/show' get 'stories/new' resources :stories resources :sentences, only: [:create] end 

和架构:

 ActiveRecord::Schema.define(version: 20180322121215) do create_table "sentences", force: :cascade do |t| t.text "content" t.integer "story_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["story_id"], name: "index_sentences_on_story_id" end create_table "stories", force: :cascade do |t| t.string "title" t.text "content" t.datetime "created_at", null: false t.datetime "updated_at", null: false end end 

如评论中所述,您可能希望您的路线看起来像:

 resources :stories do resources :sentences, only: [:create] end 

哪个会给你:

  story_sentences POST /stories/:story_id/sentences(.:format) sentences#create stories GET /stories(.:format) stories#index POST /stories(.:format) stories#create new_story GET /stories/new(.:format) stories#new edit_story GET /stories/:id/edit(.:format) stories#edit story GET /stories/:id(.:format) stories#show PATCH /stories/:id(.:format) stories#update PUT /stories/:id(.:format) stories#update DELETE /stories/:id(.:format) stories#destroy 

您可以使用以下内容:

 <%= form_tag story_sentences_path(@story) do %> ... <% end %> 

然后,正如马特所说,将你的find改为:

 @story = Story.find(params[:story_id]) 

您可以通过几种合理的方式在句子控制器中找到故事。

  1. 您可以在表单中添加一个story_id字段,并将其作为参数与句子内容一起提交。 只需确保将其添加到控制器中的sentence_params ,这样就不会被忽略。

     def sentence_params params.require(:sentence).permit(:content, :story_id) end 

    然后,您需要将控制器中的find_story方法更新为:

     @story = Story.find(sentence_params[:story_id]) 
  2. 您可以在路径文件中设置嵌套资源(其中句子资源嵌套在stories资源中)。 这将使您可以从路径本身访问story_id (即,您不需要通过表单提交story_id )。

    如果你这样做,你还需要调整控制器中的find_story方法,但这次它应该是:

     @story = Story.find(params[:story_id])