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 %>

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

フォームによって送信された params ハッシュは次のようになります。

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

ストーリーの最初のセグメントの ID を保存する方法はありますか? 代わりに、ストーリー モデル内に before_create を追加する必要があると思いますが、これを行う方法がわかりません。

4

2 に答える 2

1

私はこれに別の方法でアプローチし、数値sort_order列を追加して、 id にSegment依存して順序を決定しないようにします。次に、データベースの最初のセグメントを明示的に参照するのではなく、モデルで次のようなものを定義できます。SegmentStory

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 に答える