很抱歉,如果我的问题很愚蠢,但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
答案 0 :(得分:3)
As stated in the comments, you probably want your routes to look something like:
resources :stories do
resources :sentences, only: [:create]
end
Which will give you:
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
Which you might use something like:
<%= form_tag story_sentences_path(@story) do %>
...
<% end %>
Then, as Matt said, change your find
to:
@story = Story.find(params[:story_id])
答案 1 :(得分:0)
There are a couple of reasonable ways you can find the story in your sentences controller.
You can add a story_id
field to your form and submit it as a param along with the sentence content. Just make sure to add it to sentence_params
in the controller so it's not ignored.
def sentence_params
params.require(:sentence).permit(:content, :story_id)
end
And then you'll need to update your find_story method in the controller to:
@story = Story.find(sentence_params[:story_id])
You can set up nested resources in your routes file (where the sentences resource is nested within the stories resource). That will give you access to the story_id
from the route itself (ie. you wouldn't need to submit the story_id
through the form).
And if you go this way, you'll also need to tweak the find_story
method in the controller, but this time it should be:
@story = Story.find(params[:story_id])