2

I have a Product model:

class Product < ActiveRecord::Base
    belongs_to :subcategory

    define_index do

        # fields
        indexes subcategory.name, :as => :subcategory, :sortable => true, :facet => true

        # attributes
        has subcategory_id, created_at, updated_at

        #properties
        set_property :delta => true

Now, suppose that a user updates a subcategory name, which is the proper way to update the products delta index?

According to this documentation: http://freelancing-god.github.com/ts/en/deltas.html, a save message should be sent to the product, so in this case I should go for each product related with the subcategory and send the save message, something like this:

class Subcategory < ActiveRecord::Base
    has_many :products

    after_save :set_product_delta_flag

    private

    def set_product_delta_flag
        products.each { |product|
        product.delta = true
        product.save
     }
    end
  end

I think that this is overkilling because we have like 100.000 products per subcategory. Is this the correct way to update the delta index? Am I missing something?

After adding this:

def set_product_delta_flag
    Product.update_all ['delta = ?', true], ['subcategory_id = ?', id]
    Product.index_delta
end

I'm always receiving this error:

NoMethodError (undefined method `index_delta' for #):

So, the solution to this problem was to send the message *define_indexes* to the Product model.

After fixing this issue, everything was ok, but the delta_index was not correctly updated, I needed to do save twice to the subcategory model.

So my final solution is this one:

after_commit :set_product_delta_flag

private

def set_product_delta_flag
    Product.define_indexes
    Product.update_all ['delta = ?', true], ['subcategory_id = ?', id]
    Product.index_delta
end

Using after_commit and define_indexes is the correct solution? Its the only one that I've found.

Claudio Acciaresi
  • 31,951
  • 5
  • 33
  • 43

1 Answers1

4

Try the following instead:

def set_product_delta_flag
  Product.update_all ['delta = ?', true], ['subcategory_id = ?', id]
  Product.index_delta
end

A single SQL statement, a single delta re-indexing. Should perform far better :)

pat
  • 16,116
  • 5
  • 40
  • 46
  • Pat, I've updated the question to explain the problems I've using the proposed solution. – Claudio Acciaresi Feb 07 '11 at 16:33
  • Hi Claudio - yup, after_commit (so the transaction is saved before Sphinx does its thing) and define_indexes (to ensure Product has all the required Thinking Sphinx hooks) is the right approach. Good to know you got it all sorted. – pat Feb 10 '11 at 06:24