Working with unsaved associations
Let's say I have two model开发者_StackOverflows:
class Model1 < ActiveRecord::Base
has_many :model2
def save
self.attr = <sth. complex involving the associated model2 instances>
super
end
end
class Model2 < ActiveRecord::Base
belongs_to :model1
end
The statement in the overwritten save
method will issue a complex query (using find
[or alternatively named scopes]) to calculate some aggregate value for some of the associated Model2 instances. The problem is that when a new Model1 instance along with some Model2 instances, this query will not return anything on the first save
after the objects have been created and will return old data (the previous generation) for all consecutive save
operations.
Is there a way to use find
on the non-persisted in-memory state?
Of course: it's called #select, or #inject, or any of the other -ect methods:
class Model1 < ActiveRecord::Base
has_many :model2
before_save :update_aggregate_value
private
def update_aggregate_value
# returns sum of unit_value for all active model2 instances
self.attr = model2.select(&:active?).map(&:unit_value).sum
end
end
class Model2 < ActiveRecord::Base
belongs_to :model1
end
Remember in this case that the DB will not be hit, except if the model2 instances hadn't been loaded yet. Also, notice I used a before_save callback, instead of overriding #save. This is "safer" in that you can return false and prevent the save from proceeding.
精彩评论