2012-07-16 4 views
2

Я использую find_by_sql для выполнения SQL-запроса. Я хотел бы иметь возможность использовать Soundex и Levenshtein, но для использования Levenshtein мне нужно включить функцию в файл.Как включить пользовательскую функцию SQL

Это мой код до сих пор:

info = params[:email].split('@') 
name = info[0] 
domain = info[1] 

levenshtein = File.open("./lib/assets/mysql-function-levenshtein.sql") 

results = Domain.find_by_sql(
    "" + levenshtein + " 
    SELECT * 
    FROM domains 
    WHERE domain = '" + domain + "'" 
) 

Я понятия не имею, если просто включить его в запросе даже действует.

Какая наилучшая реализация?

Кстати файл я пытаюсь включить это: https://github.com/vyper/levenshtein-sql

+0

Пытался бегу, что? Я бы, вероятно, использовал 'File.read' вместо' File.open' или обернул вызов 'find_by_sql' в блок' File.open do ... end'. В противном случае я не слишком люблю использовать пользовательские SQL-запросы. Не могли бы вы просто определить функцию в базе данных и сделать «где» (levensthtein («leonardo», «leonardu») »)? Нет никакой реальной необходимости определять функцию каждый раз, когда вы запускаете запрос, не так ли? – Frost

+0

Да, вы правы, 'File.read' - тот, который нужно использовать. –

+0

Как я могу определить функцию в базе данных? –

ответ

5

Во-первых, я думаю, вы бы лучше просто определение этой функции в базе данных с миграцией, так что вы Wouldn» т придется определить его снова для каждого запроса, в котором вы хотите использовать:

class AddLevenShteinFunctionToDatabase < ActiveRecord::Migration 
  def up 
    levenshtein = File.read("/path/to/levenshtein.sql") 
    execute levenshtein 
  end 

    def down 
    # maybe put some code here to delete the function 
    end 
end 

с этим сделано, вы можете также добавить область к вашей Domain модели для выполнения такого рода запросов:

scope :levenshtein, lambda {|s1, s2| select("levenshein(#{s1}, #{s2})") } 

При этом, вы должны быть в состоянии написать запросы нечто вроде этого:

results = Domain.levenshtein("LEONARDO", "LEONARDU").where(:domain => domain) 
+0

Спасибо за ваш ответ, однако я волнуюсь, что использование Active Record окажет влияние на производительность. Запросов в секунду будет много, и мне сказали, что выполнение raw SQL будет намного быстрее. –

+0

В этом случае я бы рекомендовал вам написать тестовый тест для проверки того, действительно ли это так, и если да, просто используйте 'Domain.find_by_sql (« выберите levenshtein ('# {s1}', '# {s2} ') из доменов, где domain =' # {domain} ') 'вместо. – Frost

+0

Спасибо, могу ли я использовать эту хранимую функцию с помощью' find_by_sql'? –

Смежные вопросы