Re: [Rails] A rollback is not issued when dependent object before_destroy callback returns false

42 views
Skip to first unread message

Gintautas Šimkus

unread,
Aug 21, 2012, 12:34:34 AM8/21/12
to rubyonra...@googlegroups.com
Why would you want to return false from a callback and still destroy it? I think you might try to squeeze two different concepts into a single method definition: if you want to check whether or not price is lower than something and actually USE that information somewhere else, then just create another method "low_price?", and you can use it in "low_price" callback:

def low_price
  if low_price?
    # do something before the record is destroyed
  end
  true
end

def low_price?
  price <= 100
end

2012/8/20 Panayotis Matsinopoulos <pana...@matsinopoulos.gr>
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 INTO `orders` (`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 INTO `order_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)  SELECT `order_items`.* FROM `order_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 FROM `orders` WHERE `orders`.`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

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/tYWGJ6euWZQJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 


Gintautas Šimkus

unread,
Aug 21, 2012, 12:37:53 AM8/21/12
to rubyonra...@googlegroups.com
Sorry should read.

2012/8/21 Gintautas Šimkus <dihi...@gmail.com>
I think you might BE TRYING to squeeze two different concepts

Panayotis Matsinopoulos

unread,
Aug 21, 2012, 2:16:31 AM8/21/12
to rubyonra...@googlegroups.com
Thanks for your answer. See my comments below


On Tuesday, August 21, 2012 7:34:34 AM UTC+3, Dihital wrote:
Why would you want to return false from a callback and still destroy it?


No. I do not want. I think you missed the point of my post. In the example that I have written the Order Item IS NOT CORRECTLY deleted, because it has high price. The PROBLEM is that the OWNING Order is deleted, when it shouldn't.

Please, consider this as an example of an owner (Order in the example) being deleted when it shouldn't (because of the fact that the owned item (Order Item in the example) is not deleted). Do not stick too much on the business value of the example.
There may not be much, if any.


Panayotis
Reply all
Reply to author
Forward
0 new messages