1

我是 Rails 的新手,所以我可能忽略了一些简单的东西。我有一个称为故事的 Rails 模型。每个故事都有_许多片段,每个片段都属于一个故事。我使用相同的表单来创建故事及其第一个片段,方法是使用表单的 fields_for 部分并将故事模型设置为 accept_nested_attributes_for :segments。我目前能够使用该表单同时创建故事和片段。

问题是每个故事还需要存储它的第一个片段的id,但是当我保存故事时,片段还没有保存,所以它还没有id可以存储在故事中,并且在提交表单后我无法找到该段的句柄,以便我可以在创建故事之前先保存该段。所以我的问题是如何在故事中保存 first_segment_id 的记录?

以下代码可能是相关的:

在 app/models/story.rb

class Story < ActiveRecord::Base
    attr_accessible :segments_attributes
    has_many :segments
    accepts_nested_attributes_for :segments
end

在 app/models/segment.rb

class Segment < ActiveRecord::Base
  attr_accessible :words
  belongs_to :story
end

在 app/views/stories / _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 %>

在应用程序/控制器/故事_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

表单提交的 params 哈希类似于:

{ "story"=>{ Various_other_story_fields,
 "segments_attributes"=>{"0"=>{"words"=>"dfsdsa"}}},
 "commit"=>"Create Story"}

有没有办法在故事中保存第一段的 id?我想也许我需要在我的故事模型中添加一个 before_create ,但我不知道该怎么做。

4

2 回答 2

1

我会以不同的方式处理这个问题,添加一个数字sort_order列,Segment以便您不依赖Segmentid 来确定它们的顺序。然后您可以在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
于 2013-04-01T00:41:55.620 回答
1

您应该能够执行以下操作:

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 添加到您的分段表中。

于 2013-04-01T01:18:44.173 回答