2016-10-12 3 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] как в params[:booking][:product_id]. Кто-нибудь знает почему?

ответ

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 

Однако остальная часть вашей логики контроллера запутана и сложна. Я бы различные маршруты для update и create:

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

Эта строка всегда терпит неудачу '@booking = @ order.bookings.find_by (product_id: params [: product_id])', когда я делаю 'if @ booking'. Вот почему я в настоящее время получаю совершенно новые заказы все время. –

+0

Я также выяснил, что параметры [..] не работают. Для этого я должен сделать отдельную частную функцию. Моя функция обновления является отдельной, потому что обновление в самом порядке. –

+0

Я решил: Видимо, мне нужно было захватить параметры, добавив [: booking], как в params [: booking] [: product_id]. Быть может, почему? –