2

我有三个模型:Booking、ExtraNight 和 BookedExtraNight。运行 Rails 2.3.11

预订:

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

特夜:

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

预订加晚:

belongs_to  :extra_night
belongs_to  :booking

现在由于应用程序的工作方式,在创建booked_extra_night 时存在预订。使用预订更新操作创建了一个预定的额外之夜。在视图中,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 副本时按下提交(更新操作)。

见日志:

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

如您所见,创建了两条相同的记录,现在如果我要构建 4 个预定的额外夜晚并按提交,我最终会得到 8 条记录。

我还发现,如果我在创建预订的同时创建一个booked_extra_night 记录,那么我可以在不重复的情况下添加任意数量的数据。据我所知,这发生在所有 2.3.x 版本的 rails 上,所以这显然是我做错了。任何帮助将不胜感激,因为它让我很受用。

谢谢!

4

2 回答 2

0

我也遇到过这个问题,我的解决方案是在我的控制器中,不使用构建,而是使用 new 并提供 parent 参数。

在我的代码中提取..而不是使用

@new_brand = @company.brands.build/new

我用

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

第一个将此对象作为空对象添加到@company,然后当您提交它时,在您的创建操作中创建另一个新对象。

第二个只是为了表单的目的在内存中创建一个新对象,但是当值提交到创建操作时,没有对象与公司相关联

于 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 回答