2

予約、ExtraNight、BookedExtraNightの3つのモデルがあります。ランニングレール2.3.11

予約:

has_many :extra_nights, :through => :booked_extra_nights
has_many :booked_extra_nights, :dependent => :destroy

ExtraNight:

has_many :booked_extra_nights, :dependent => :destroy
has_many :bookings, :through => :booked_extra_nights

BookedExtraNight:

belongs_to  :extra_night
belongs_to  :booking

これで、アプリケーションの動作方法により、booked_extra_nightが作成されたときに予約が存在します。booked_extra_nightは、BookingUpdateアクションで作成されます。ビューでは、booked_extra_nightは以下を使用して構築されます。

<% unless @booking.booked_extra_nights.exists? %>
   <% @booking.booked_extra_nights.build %>
<% end %>

私はnested_form_for@bookingとf.fields_for:booked_extra_nightsを使用してbooked_extra_nightsを作成します。

これで、booked_extra_nightの2つのコピーが作成されたときに送信(更新アクション)を押すまで、すべてが正常に機能します。

ログを参照してください:

Processing BookingsController#update (for 127.0.0.1 at 2011-02-21 07:44:22) [PUT]
Parameters: {"action"=>"update", "_method"=>"put",   "authenticity_token"=>"b/M+VjMxA8RFqbubhBeF494B/zhxi/2Eb3EtoCoRLx0=",  "id"=>"5b2jwg7qw5na3vz4nt", "booking"=>{"booked_extra_nights_attributes"=>{"0"=> {"number_of_days"=>"2", "from_date(1i)"=>"2011", "from_date(2i)"=>"9", "from_date(3i)"=>"1",  "_destroy"=>"", "extra_night_id"=>"7"}}}, "controller"=>"bookings"}
Booking Load (1.3ms)   SELECT * FROM "bookings" WHERE ("bookings"."random_url_key" =  '5b2jwg7qw5na3vz4nt') LIMIT 1
Variant Load (0.6ms)   SELECT * FROM "variants" WHERE ("variants"."id" = 27) 
SQL (0.1ms)   BEGIN
SQL (0.7ms)   INSERT INTO "booked_extra_nights" ("number_of_days", "created_at",   "updated_at", "booking_id", "from_date", "extra_night_id") VALUES(2, '2011-02-21  06:44:22.525154', '2011-02-21 06:44:22.525154', 69, '2011-09-01', 7) RETURNING "id"
SQL (0.8ms)   COMMIT
SQL (0.6ms)   BEGIN
SQL (0.6ms)   INSERT INTO "booked_extra_nights" ("number_of_days", "created_at",  "updated_at", "booking_id", "from_date", "extra_night_id") VALUES(2, '2011-02-21 06:44:22.544452', '2011-02-21 06:44:22.544452', 69, '2011-09-01', 7) RETURNING "id"
SQL (25.8ms)   COMMIT
SQL (0.1ms)   BEGIN
Booking Update (0.6ms)   UPDATE "bookings" SET "updated_at" = '2011-02-21 06:44:22.575409', "aasm_state" = 'step3' WHERE "id" = 69
SQL (0.5ms)   COMMIT
Redirected to http://localhost:3000/bookings/5b2jwg7qw5na3vz4nt/step3

ご覧のとおり、2つの同一のレコードが作成されているので、4つのbooked_extra_nightsを作成して送信を押すと、8つのレコードになります。

また、予約の作成と同時にbooked_extra_nightレコードを作成すると、重複することなく上記を実行するだけで追加できることもわかりました。これは、私が知る限り、すべての2.3.xバージョンのレールで発生するため、明らかに私が間違っていることです。それは私の頭をやっているので、どんな助けでも大歓迎です。

ありがとう!

4

2 に答える 2

0

私もこの問題を抱えていました。私の解決策は、ビルドを使用せず、newを使用して親パラメーターを指定することでした。

私のコードで抽出します。使用する代わりに

@new_brand = @company.brands.build/new

私が使う

@new_brand = Brand.new(:company => @company)

最初にこのオブジェクトを空のオブジェクトとして@companyに追加し、次にそのオブジェクトを送信すると、createアクション内で別の新しいオブジェクトを作成します。

2つ目は、フォームの目的でメモリ内に新しいオブジェクトを作成するだけですが、値が作成アクションに送信されると、会社に関連付けられたオブジェクトはありません。

于 2011-02-21T15:43:12.383 に答える
0

ありがとう、ラボット!悲しいことに、あなたは私を正しい軌道に乗せましたが、更新アクションは混乱していました。私はそれをリファクタリングしました、そして今すべてがうまくいきます、私は二重の節約が私が最初に予約を更新し、次にリダイレクトし、そしてAASMを通して予約を再び更新することと関係があったと思います。

以下は古い更新アクションです(私はそれが混乱したとあなたに言いました):

def update
  @booking = Booking.find_by_random_url_key(params[:id])
  @variant = @booking.variant
  if params[:back_button]
    if @booking.aasm_state == "step2"
      redirect_to booking_step1_url(@booking)
    elsif @booking.aasm_state == "step3"
      redirect_to booking_step2_url(@booking)
    elsif @booking.aasm_state == "step4"
      redirect_to booking_step3_url(@booking)
    elsif @booking.aasm_state == "step5"
      redirect_to booking_step4_url(@booking)
    end
    @booking.previous!
  else
    if @booking.update_attributes(params[:booking]) && @booking.aasm_state == "step1"
      redirect_to booking_step2_url(@booking)
      @booking.next!
    elsif @booking.update_attributes(params[:booking]) && @booking.aasm_state == "step2"
      @booking.next!
      redirect_to booking_step3_url(@booking)
    elsif @booking.update_attributes(params[:booking]) && @booking.aasm_state == "step3"
      redirect_to booking_step4_url(@booking)
      @booking.next!
    elsif @booking.update_attributes(params[:booking]) && @booking.aasm_state == "step4"
      redirect_to booking_url(@booking)
      @booking.next!
    end
  end
end

そして、これは新しい、リファクタリングされた更新アクションです。

  def update
    @booking = Booking.find_by_random_url_key(params[:id])
    @variant = @booking.variant
    if params[:back_button]
      @booking.previous!
      redirect_to :controller => "bookings", :action => "#{@booking.aasm_state}", :id => @booking
    else
      @booking.update_attributes(params[:booking])
      @booking.next!
      redirect_to :controller => "bookings", :action => "#{@booking.aasm_state}", :id => @booking
    end
  end

同じ機能で、多くの行が少なくなります。そして、それは重複した余分な夜を作成しません。

ありがとう、ラボット。ビューとモデルの内容を何度か変更しようとしても成功しなかったので、あなたの答えは私に考えさせられました。それが他のすべてのために働いたので、私はちょうどコントローラーが働いたと思いました。

于 2011-02-21T21:38:02.050 に答える