未定义的方法或我的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])
您可以通过几种合理的方式在句子控制器中找到故事。
-
您可以在表单中添加一个
story_id
字段,并将其作为参数与句子内容一起提交。 只需确保将其添加到控制器中的sentence_params
,这样就不会被忽略。def sentence_params params.require(:sentence).permit(:content, :story_id) end
然后,您需要将控制器中的find_story方法更新为:
@story = Story.find(sentence_params[:story_id])
-
您可以在路径文件中设置嵌套资源(其中句子资源嵌套在stories资源中)。 这将使您可以从路径本身访问
story_id
(即,您不需要通过表单提交story_id
)。如果你这样做,你还需要调整控制器中的
find_story
方法,但这次它应该是:@story = Story.find(params[:story_id])