2016-10-12 12 views
0

私は製品を持っています。
私に注文があります。
私は間に予約をしています。最初のレールまたは初期化されないレール

私は予約から商品を予約するたびに、新しい予約を保存します。

それはする必要があります

  1. それは、この製品から作られた最初だときに、新しい予約を保存します。
  2. 新しい予約は行いませんが、製品が既に予約されている場合は、古い予約を検索して上書きします。
  3. ご注文の製品がすでに予約されていて、変更が加えられていない場合は、データベーストランザクションは行われません。
def create 
    @order = current_order 
    @booking = @order.bookings.where(product_id: params[:product_id]).first_or_initialize 
    product = @booking.product 
    if @booking.new_record? 
     @booking.product_name = product.name 
     @booking.product_price = product.price 
    else 
    @booking.product_quantity = params[:product_quantity] 
    @booking.save 
    @order.sum_all_bookings 
    @order.save 
    end 

動作しません。

def create 
    @booking = @order.bookings.find_by(product_id: params[:booking][:product_id]) 
    if @booking 
     @booking.product_quantity = params[:booking][:product_quantity] 
     @booking.save 
    else 
     @booking = @order.bookings.new(booking_params) 
     @product = @booking.product 
     @booking.product_name = @product.name 
     @booking.product_price = @product.price 
    end 
    @order.save 
    end 

どうやら私はparams[:booking][:product_id]に似[:booking]を追加することによって、のparamsをつかむために必要な:働いた後

。なぜ誰が知っていますか?

答えて

0

あなたは、セットアップの関係を適切とデータベースのインデックスを使用しては、一意性を確保するために必要があり、重複を避けるために

@order.bookings.find_or_initialize_by(product_id: params[:product_id]).tap do |b| 
     # your business logic here 
    end 
+0

どういうわけか、パラメータが正しく機能していません。 –

0

を試すことができます。

class Order 
    has_many :bookings 
    has_many :products, though: :bookings 
end 

class Booking 
    belongs_to :order 
    belongs_to :product 
    validates_uniqueness_of :order_id, scope: :product_id 
end 

class Product 
    has_many :bookings 
    has_many :orders, though: :bookings 
end 

ここでの検証は、アプリケーションレベルでの重複の挿入を防止します。しかし、それはまだ競争条件になりがちです。

class AddUniquenessContstraintToBooking < ActiveRecord::Migration[5.0] 
    def change 
    add_index :bookings, [:order_id, :product_id], unique: true 
    end 
end 

ただし、残りのコントローラロジックは混乱しすぎ、複雑すぎます。 Iだろうupdatecreateのための明確な路線:

class BookingsController < ApplicationController 

    before_action :set_order, only: [:create, :index] 
    before_action :set_order, only: [:create, :index] 

    # POST /orders/:order_id/bookings 
    def create 
    @booking = @order.bookings.new(booking_params) 
    if @booking.save 
     redirect_to @order 
    else 
     render :new 
    end 
    end 

    # PATCH /bookings/:id 
    def update 
    if @booking.update(:booking_params) 
     redirect_to @order 
    else 
     render :edit 
    end 
    end 

    private 

    def set_order 
    @order = Order.find(params[:id]) 
    end 

    def set_booking 
    @booking = Booking.find(params[:id]) 
    end 

    def booking_params 
    params.require(:booking) 
      .permit(:product_id) 
    end 
end 

別の方法としては、accepts_nested_attributesを使用することです - しかし、それをシンプルに保つようにしてみてください。

+0

'if @ booking'を実行すると、この行は' @booking = @ order.bookings.find_by(product_id:params [:product_id]) 'に失敗します。それで、私は現在、常に新しい予約をしています。 –

+0

私も、params [..]が動作していないことを知りました。私はそれのために別の私的な機能を作らなければなりません。更新はオーダーそのもので修正されているので、私の更新機能は別です。 –

+0

私はそれを解決しました:明らかに、params [:booking] [:product_id]のように[:booking]を追加することによって、paramsを取得する必要がありました。なぜ起こったの? –

関連する問題