Question

This question is related to this: thinking-sphinx index minimum

I have three models: Product, Price, PriceType

class Product < ActiveRecord::Base
  has_many :prices

class Price
  belongs_to :product
  belongs_to :price_type

  validates :price_type, :value, :product, presence: true
  validates :price_type, uniqueness: { scope: :product }

class PriceType
  has_many :prices

Product has_many prices (some prices to some user types, so there is a price_type value). One product has unique price for some price_type.

I need to filter and sort by price values and price_type.

If there isn't such price with such price type, it should be replaced by price with another price type (I should pass price type id).

ThinkingSphinx::Index.define :product, with: :active_record do
  indexes name
  indexes k1c
  indexes catalogue_code
  indexes created_at, sortable: true

  # sort by price
  has prices.id, as: :price_ids
  has prices.price_type_id, as: :price_type_ids
#  PriceType.all.each do |price_type|
#    has "prices.value(CASE WHEN prices.type_id = #{price_type.id} END)", as: "price_type_#{price_type.id}".to_sym, type: :float
#  end

  has :category_id
  has :brand_id
  has :kind_cd
end

I tried to do something like that, but with no luck (commented out).

Was it helpful?

Solution

This was discussed in a chat room, and we figured out a solution that works for ordering by prices of specific price types by putting the following within the index definition:

PriceType.all.each do |price_type|
  has "(CASE WHEN prices_#{price_type.id} IS NOT NULL THEN prices_#{price_type.id}.value ELSE NULL END)", as: "price_type_#{price_type.id}".to_sym, type: :float
  join "LEFT OUTER JOIN prices AS prices_#{price_type.id} ON prices_#{price_type.id}.product_id = products.id AND prices_#{price_type.id}.price_type_id = #{price_type.id}"
  group_by "price_type_#{price_type.id}"
end

This is not particularly ideal from a performance perspective - and the Sphinx setup will need to be rebuilt every time a new PriceType is added to the system. However, if this is not a common occurrence, and there's not too many of them, it's a feasible solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top