我是Rails新手,所以可能我忽略了一些简单的东西。我有一个叫做故事的Rails模型。每个故事都有许多片段,每个片段都属于一个故事。我使用相同的表单创建故事及其第一个片段,方法是使用表单的fields_for部分并将故事模型设置为accepts_nested_attributes_for:segments。我目前能够使用的形式,同时创建一个故事和一个片段。
问题是每个故事还需要存储其第一个片段的id,但是当我保存故事时,片段还没有保存,所以它还没有id存储在故事中,并且在提交表单后我还无法找到片段的句柄,因此我可以在创建故事之前先保存片段。所以我的问题是我如何保存firstrongegment_id在故事中的记录?
下面的代码可能是相关的:
在app/模型/story.rb
class Story < ActiveRecord::Base
attr_accessible :segments_attributes
has_many :segments
accepts_nested_attributes_for :segments
end
在app/模型/segment.rb
class Segment < ActiveRecord::Base
attr_accessible :words
belongs_to :story
end
在app/views/故事/ _ form.html.erb
<%= form_for(@story) do |f| %>
#...stories fields...
<%= f.fields_for :segments do |segment_form| %>
<div class="field">
<%= segment_form.label :words %><br />
<%= segment_form.text_area :words %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
在app/controllers/stories_ controller.rb
def new
@story = Story.new
@segment = @story.segments.build
# If I try replacing the above with @segment = @story.segments.create
# then I get the error message "You cannot call create unless the
# parent is saved," which is problematic because I need to find some way
# to get the id of @segment to save in the parent story, but the segment
# won't have an id until after it has been saved.
respond_to do |format|
format.html # new.html.erb
format.json { render json: @story }
end
end
def create
@story = Story.new(params[:story])
# @segment.save
# @story.first_segment_id = @segment.id
# If I uncomment the above two lines, I get the error message
# "undefined method `save' for nil:NilClass". It appears that
# @segment hasn't been passed from the "new" method above to
# this method as a handle of the first segment created, so I'm not
# able to save it to get an id for it before saving the story.
# Is there some way to save the segment here?
respond_to do |format|
#...if @story.save...
end
end
表单提交的参数哈希看起来像:
{ "story"=>{ Various_other_story_fields,
"segments_attributes"=>{"0"=>{"words"=>"dfsdsa"}}},
"commit"=>"Create Story"}
是否有办法在故事中保存第一个片段的id ?我想也许我需要添加一个before_create在我的故事模型,而不是,但我不确定如何做到这一点。
我会以不同的方式处理,将数字sort_order
列添加到Segment
,以便您不依赖Segment
id来确定它们的顺序。然后,您可以在Story
模型上定义如下内容,而不是显式引用数据库中的第一个段:
def first_segment
segments.order(:sort_order).first
end
如果您确定需要在故事中存储第一个片段ID,您可以.save
故事,以便它知道它的ID,保存它的子节点,并知道它们的ID。比如:
def create
@story = Story.new(params[:story])
@story.save # Save the story and its child segment so that they both have IDs
@story.first_segment_id = @story.segments.first.id
@story.save
...
end
您应该能够做如下操作:
class Story < ActiveRecord::Base
attr_accessible :segments_attributes
has_many :segments
has_one :first_segment
accepts_nested_attributes_for :segments
end
def new
@story = Story.new
@segment = @story.segments.build
@story.first_segment = @segment
...
您必须将story_id添加到您的分段表