0

I have three Models

Bid, Printer, Order

A printer can have many bids but only one an order.

Im having trouble validating that exact case, a printer can have many bids, but only one bid per order

Are there any validations that have this built in to ActiveModel or ActiveRecord? If not any ideas on how to ensure a printer can only have one bid per order?

class Bid < ActiveRecord::Base
  belongs_to :printer
end

class Order < ActiveRecord::Base
  belongs_to :user
  has_many :bids
end

class Printer < ActiveRecord::Base
  has_many :orders, through: :bids
  has_many :bids
end
Seal
  • 1,060
  • 1
  • 12
  • 31

2 Answers2

0

There might be a slicker way to do this, but you can always just pass a block to validate. Maybe something like this?

class Order < ActiveRecord::Base
  belongs_to :user
  has_many :bids
end

class Bid < ActiveRecord::Base
  belongs_to :printer
end

class Printer < ActiveRecord::Base
  has_many :orders, through: :bids
  has_many :bids

  validate do
    order_ids = orders.pluck(:bid_id)
    dups = order_ids.detect{ |id| order_ids.count(id) > 1 }
    errors.add(:bids, 'Only one order per bid per printer') if dups.any?
  end
end
double.emms
  • 483
  • 7
  • 14
0

a printer can have many bids, but only one bid per order

In other words, the values of pairs (order_id, printer_id) must be unique in bids table, right? So you only need validate the uniqueness of (order_id, printer_id) in Bid model like

validates :order_id, uniqueness: { scope: :printer_id }

Ok, to clarify my answer, I have an example of bids table here.

+--------+----------+------------+
| bid_id | order_id | printer_id |
+--------+----------+------------+
|      1 |        1 |          1 |
|      2 |        1 |          2 |
|      3 |        2 |          2 |
|      4 |        2 |          3 |
+--------+----------+------------+

It's all good: a printer has one bid per order. But what will happen if we add a record like [5, 2, 3] into the table? The printer with printer_id = 3 will have 2 bids (with bid_id = 4,5)! The condition is exactly the same with values of pairs (order_id, printer_id) are not unique here!

+--------+----------+------------+
| bid_id | order_id | printer_id |
+--------+----------+------------+
|      4 |        2 |          3 |
|      5 |        2 |          3 |
+--------+----------+------------+
Van Huy
  • 1,607
  • 1
  • 13
  • 16