Rails Autocomplete работает локально, но не на Heroku, возможно, проблема с MySQL / Postgre - PullRequest
1 голос
/ 28 декабря 2011

Я использую гем rails3-jquery-autocomplete для автозаполнения поля (продукта) в форме в моем приложении rails 3. Пользователь может ввести название продукта или код продукта, которые являются строковыми столбцами в таблице продуктов. Локально все работает нормально, но на героку вылетает запрос ajax со стандартной ошибкой 500 heroku:

We're sorry, but something went wrong (500)

Я думаю, что это может быть проблема postgre / sql - я использую mysql локально для разработки, но heroku работает на базе данных postgre sql, и я делаю следующий запрос в функции, которая получает вызовы по запросу автозаполнения ajax:

  def get_autocomplete_items(parameters)
    items = Product.select("DISTINCT CONCAT_WS(' ', product_code, title, id) AS full_name, product_code, title, id").where(["CONCAT_WS(' ', product_code, title) LIKE ?", "%#{parameters[:term]}%"])
  end

Локально, это вернуло бы мне массив в формате json, включая все совпадающие produc_ids и имена:

[{"id":"9","label":"xt-pnt-dress_45 - Catherine Malandrino","value":"xt-pnt-dress_45 - Catherine Malandrino"}, ... ]

Если у кого-нибудь есть идея, как изменить этот запрос, чтобы он соответствовал heroku или любой другой идее, я был бы очень благодарен. ТНХ.

1 Ответ

3 голосов
/ 28 декабря 2011

Heroku использует PostgreSQL 8.3 для общих баз данных и 9.0 для выделенных баз данных .Ни версия 8.3 , ни версия 9.0 не имеют функции concat_ws, эта функция доступна только в версии 9.1 + .

Вы можете объединитьхотя строки вручную:

items = Product.select("DISTINCT product_code || ' ' || title || ' ' || id AS full_name, product_code, title, id").where(["product_code || ' ' || title LIKE ?", "%#{parameters[:term]}%"])

Это будет работать, пока ни один из product_code, title и id не равен NULL.Если у вас могут быть значения NULL, вы можете обернуть их COALESCE (например, COALESCE(product_code || ' ', '')), чтобы превратить их в пустые строки.

В качестве альтернативы, вы можете позаботиться о full_name в Ruby:

def full_name
    [product_code, title, id].reject(&:blank?).join(' ')
end

и иметь отдельный сгенерированный столбец для LIKE или проверить оба столбца с помощью LIKE:

where('product_code LIKE ? OR title LIKE ?', "%#{parameters[:term]}%", "%#{parameters[:term]}%")
where('produce_code LIKE :pat OR title LIKE :pat', :pat => "%#{parameters[:term]}%")

Кроме того, вы должны знать, что LIKE в MySQL нечувствителен к регистру, а PostgreSQL - нет, поэтому вы можете захотеть использовать нижний регистрвсе, чтобы избежать путаницы:

where('LOWER(product_code) LIKE :pat OR LOWER(title) LIKE :pat', :pat => "%#{parameters[:term].downcase}%")

Поскольку || - это логическое ИЛИ в MySQL , объединяющее три строки в Ruby (т.е. def full_name) и проверяющее product_code иtitle с отдельными нижестоящими LIKE - это, вероятно, самое чистое портативное решение.

Переключение среды разработки на PostgreSQL также было бы хорошей идеей, и согласование версий со средой развертывания также было бы хорошей идеей.Существуют и другие различия, которые могут вызвать проблемы.

...