Rails创建连接表对象不应该创建,但在特殊情况下更新

时间:2016-10-08 10:00:32

标签: ruby-on-rails jointable

在网上商店,我有一个预订,需要知道订单中是否已经预订。我完成了所有工作,但随后细节......

...现在'在产品上预订'(或者用普通英语:将产品添加到购物车中)在每种情况下都会在订单列表中添加全新的预订。当这个产品已经预订一次时,它不应该只改变数量。

这么容易吗?只需一个简单的if语句,整个过程就可以了。

bookings_controller.rb

  def create
    @order = current_order
    # If product has already been booked
    if @order.bookings.where(product_id: params[:product_id]).exists?
      # Then: Only alter the quantity in the booking.
      @booking = @order.bookings.where(product_id: params[:product_id])
      @booking.product_quantity = params[:product_quantity]
    else
      # Else: Make a new booking.
      @booking = @order.bookings.new(booking_params)
      @product = @booking.product
      @booking.product_name = @product.name
      @booking.product_price = @product.price
    end
    @order.sum_all_bookings 
    @order.save
  end

  # ...

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

似乎不起作用。

如何在if语句中进行检查? 或者我应该采用完全不同的路线来更新预订?

修改

在gmcnaughton回答后,我尝试了这种形状的各种组合。我得到多个条目或根本没有条目。这个没有给我任何参赛作品。

bookings_controller.rb

  def create
    @order = current_order
    @booking = @order.bookings.find_or_create_by(product_id: params[:product_id])
    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

我是否也可以控制预订id?但这没有任何意义,因为在找到现有预订的情况下,它应该就在那里。

我可能是通过remote: true form来解雇预订吗?

修改2

也不行:

bookings_controller.rb

  def create
    @order = current_order
    @booking = @order.bookings.where(product_id: params[:product_id]).first_or_initialize
    if @booking.new_record?
      @booking.product_id = params[:product_id]
      product = @booking.product
      @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

编辑3

也许这与它有关:

categories_controller.rb / Shop

def index
    @categories = Category.all.order(name: :asc)
    # Voor het inzien van wat al geselecteerd is.
    @order = current_order
    # Voor het aanslaan van een nieuwe booking.
    @booking = current_order.bookings.new
  end

这基本上列出了整个初始商店。 @booking用于构建每个产品的形式。

以下工作:

  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

显然我需要通过在[:booking]中添加params[:booking][:product_id]来获取参数。谁知道为什么?

1 个答案:

答案 0 :(得分:0)

这个想法是对的,但我认为你错过了对.first的调用:

@booking = @order.bookings.where(product_id: params[:product_id])
  => #<ActiveRecord::Relation>

应该是:

@booking = @order.bookings.where(product_id: params[:product_id]).first
  => #<Booking>

...否则你正在更新关系,而不是Booking模型。您可能还想在修改后调用@booking.save

另外,ActiveRecord还有first_or_initializefirst_or_create帮助器,可以让您找到匹配的实例或构建/创建一个新实例:

@booking = @order.bookings.where(product_id: params[:product_id]).first_or_initialize
if @booking.new_record?
  @product = @booking.product
  ...other stuff for new record...
else
  @booking.product_quantity = params[:product_quantity]
end
@booking.save