Ruby on Rails Tuesday, January 3, 2012

On Tue, Jan 3, 2012 at 11:14 PM, Linus Pettersson <linus.pettersson@gmail.com> wrote:
Hi!

I have an app with products, categories, subcategories and resellercategories.

Products....

belongs_to :resellercategory
has_one :subcategory, :through => :resellercategory
has_one :category, :through => :subcategory

So, there are a lot of resellercategories that are (manually) mapped to my fewer subcategories.

I have a before_save in my products model that sets if the product is complete:

  def check_complete
    self.complete = !image_small.blank? && !subcategory.blank?
    nil
  end

So, if the resellercategory that the product is related to is mapped to a subcategory, the product is marked as "complete". However, at the moment it is only updated when the product is saved, I also want it to be updated when the resellercategory is mapped to a subcategory.

Is there any good way to do this? Should I create an after_save in my resellercategory that iterates through all the products and re-saves all of them to get the field updated?
Any easier/more effective way?


I am not sure I follow exactly, but ... 

Answer 1:

I assume this
" ... when the resellercategory is mapped to a subcategory ..."
creates (or modifies) a ResellerCategory object (and saves it
later to the database)?

So as you suggest: 
"... Should I create an after_save in my resellercategory that ..."
updates all associated products. Instead of
"... iterates through all the products and re-saves all of them to get the field updated? ..."
you could use an update_all , but that seems quite low-level database
hacking (no models instantiated, no before/after filters ...).


#untested code !!

Product.where(:reseller_category_id => reseller_category.id).update_all(:complete => true)

This does not feel comfortable, but it would probably work ...

Answer 2:

In reality, the Product.complete column is a de-facto cache for information
that is already present in the database. Unless your have real performance
problems associated with it, I would try to make a scope

class Product < ActiveRecord::Base
  scope :complete ...

that limits the products to those that are complete (that is, they have
a category and a small_image). Then Product.complete.where. ...
will inlcude the correct SQL to only select the complete products,
_without_ the implicit caching problem that you are facing now.

Very true:

> There are only two hard things in Computer Science: cache
> invalidation and naming things.
>
> Phil Karlton

HTH,

Peter

--
Peter Vandenabeele
http://twitter.com/peter_v

--
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 rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

No comments:

Post a Comment