greyoxide
greyoxide

Reputation: 1287

Rails - Find similar Products

I have two models

class Category < ActiveRecord::Base
  has_many :products
end

class Product < ActiveRecord::Base
  has_many :photos
  belongs_to :category

  def self.similar(product)
    where("name LIKE ?", "#{product.name}%").limit(4)
  end
end

I would like the self.similar method to product products which are similar to the argument passed to it(product).

The trouble Im having is that this method only returns products which match the argument perfectly. Im wondering if its possible to set the tolerance of this method to product a broader range of products rather than ones which match the argument perfectly? Or perhaps another superior way to produce an array of similar products.

Upvotes: 0

Views: 1528

Answers (3)

Roman
Roman

Reputation: 9451

If you don't want to/can't install a gem, then you can use Postgres' levenshtein (if it's installed):

Model.select("*, levenshtein(LOWER(name) , '#{thing_name.downcase}') AS fuzzydist").order('fuzzydist ASC').first

Upvotes: 1

Matthias
Matthias

Reputation: 4375

You must simple change your where query to following:

def self.similar(product)
  where("name LIKE ?", "%#{product.name}%").limit(4)
end

and your LIKE query should work..with the % at the start and the end also not exactly matching results will be returned..

Upvotes: 1

Nicola Miotto
Nicola Miotto

Reputation: 3706

I had a very good experience using fuzzy_match. There is no built in ActiveRecord nor Rails nor Ruby support for it otherwise.

So your code would then become more or less

require 'fuzzy_match'

class Category < ActiveRecord::Base
  has_many :products
end

class Product < ActiveRecord::Base
  has_many :photos
  belongs_to :category

  def self.similar(product)
    fz = FuzzyMatch.new(Product.all, :read => :name)
    return fz.find(product.name).limit(4)
  end
end

Upvotes: 0

Related Questions