Hi,
I am wondering whether this is the designed behavior of ActiveRecord,
when,
to me, it is not the expected one.
I have a simple model design with an Order having many Order Items and
an
Order Item belonging to an Order. The has_many association on Order has
a
:dependent => :destroy option.
Also, the Order Item has a before_destroy function that would check the
price of the Order Item. If the price is above 100, it returns false and
does not allow the Order Item to be destroyed.
The classes codes has as follows:
class Order < ActiveRecord::Base
attr_accessible :order_code
has_many :order_items, :inverse_of => :order, :dependent => :destroy
end
class OrderItem < ActiveRecord::Base
attr_accessible :price, :order_id
belongs_to :order, :inverse_of => :order_items
before_destroy :low_price
protected
def low_price
if price <= 100
puts “I have low price…I can be deleted”
true
else
puts “I have high price…I cannot be deleted”
false
end
end
end
The problem is that when I am issuing a destroy on an instance of an
order
that has an order item that has price > 100, then the order item is not
deleted, but the order does. Here are the console commands and output:
rails c
Loading development environment (Rails 3.2.8)
1.9.3-p194 :001 > o = Order.new :order_code => ‘first order’
=> #<Order id: nil, order_code: “first order”, created_at: nil,
updated_at: nil>
1.9.3-p194 :002 > o.save!
(0.1ms) BEGIN
SQL (0.2ms) INSERT INTOorders
(created_at
,order_code
,
updated_at
) VALUES (‘2012-08-20 08:14:20’, ‘first order’, ‘2012-08-20
08:14:20’)
(2.0ms) COMMIT
=> true
1.9.3-p194 :003 > o.order_items << OrderItem.new(:price => 110)
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTOorder_items
(created_at
,order_id
,
price
,updated_at
) VALUES (‘2012-08-20 08:14:31’, 5, 110,
‘2012-08-20
08:14:31’)
(0.5ms) COMMIT
OrderItem Load (0.3ms) SELECTorder_items
.* FROMorder_items
WHERE
order_items
.order_id
= 5
=> [#<OrderItem id: 4, order_id: 5, price: 110, created_at: “2012-08-20
08:14:31”, updated_at: “2012-08-20 08:14:31”>]
1.9.3-p194 :004 > o.destroy
(0.2ms) BEGIN
I have high price…I cannot be deleted
SQL (1.0ms) DELETE FROMorders
WHEREorders
.id
= 5
(1.8ms) COMMIT
=> #<Order id: 5, order_code: “first order”, created_at: “2012-08-20
08:14:20”, updated_at: “2012-08-20 08:14:20”>
1.9.3-p194 :005 >
Can somebody explain to me, why the failure of the dependent object
destroy
method does not trigger a rollback?
Thanks in advance
Panayotis