Reputation: 1287
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
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
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
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