Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make ActiveRecord bump updated_at on new has_many association

Tags:

When adding records to a has_many association and saving the parent, that parent's updated_at is not bumped:

order = Order.new order.save pp order   => #<Order id: 3, created_at: "2013-04-18 15:25:09", updated_at: "2013-04-18 15:25:09">  order.line_items << LineItem.new() pp order.line_items   => [#<LineItem id: 4, order_id: 3, created_at: "2013-04-18 15:26:16", updated_at: "2013-04-18 15:26:29", product_id: 123>]  order.save pp order.reload   => #<Order id: 3, created_at: "2013-04-18 15:25:09", updated_at: "2013-04-18 15:25:09"> 

This makes sense, beacause Order it not touched; the foreign key lives on the LineItem.

However, in this case, I'd like to query the Order and find only Orders that have recieved new LineItems in the last 30 minutes (i.e: were "updated" in the last 30 minutes).

I am not sure what is best to do here, and how I could achieve this easily. Is there some flag or method I could set to have AR update the parents updated_at like described? Or should I do this via some hook? If so, what hook? Or should I store this timestamp in a different column?

Note that I could query the line_items.updated_at trough a join(:line_items), but that would probably make my code more cluttered and less performant: or is this the preferred way for such issues in Rails?

like image 814
berkes Avatar asked Apr 18 '13 16:04

berkes


2 Answers

You need to include touch: true along with belongs_to :order association.

class Order < ActiveRecord::Base   has_many :line_items end   class LineItem < ActiveRecord::Base   belongs_to :order, touch: true end 

This will update the updated_at column for the associated order. More docs here

like image 109
benchwarmer Avatar answered Oct 22 '22 11:10

benchwarmer


You can use the touch option, as shown below.

class LineItems < ActiveRecord::Base   belongs_to :order, :touch => true   ... end 

This will update the "update_at" of the parent Order whenever the lineitem is saved or destroyed.

Quoting from http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html,

:touch

If true, the associated object will be touched (the updated_at/on attributes set to now) when this record is either saved or destroyed. 

If you specify a symbol, that attribute will be updated with the current time in addition to the updated_at/on attribute.

like image 31
manoj Avatar answered Oct 22 '22 10:10

manoj