Запрос Rails 3 LIKE вызывает исключение при использовании двойного двоеточия и точки - PullRequest
2 голосов
/ 25 сентября 2010

В rails 3.0.0 следующий запрос работает нормально:

Author.where("name LIKE :input",{:input => "#{params[:q]}%"}).includes(:books).order('created_at')

Тем не менее, когда я ввожу в качестве строки поиска (таким образом, содержит двойное двоеточие, за которым следует точка):

aa: .bb

Я получаю следующее исключение:

ActiveRecord :: StatementInvalid: SQLite3 :: SQLException: неоднозначное имя столбца: creation_at

В журналах есть SQL-запросы:

with aa as input:
Author Load (0.4ms)  SELECT "authors".* FROM "authors" WHERE (name LIKE 'aa%') ORDER BY created_at
Book Load (2.5ms)  SELECT "books".* FROM "books" WHERE ("books".author_id IN (1,2,3)) ORDER BY id

with aa:.bb as input:
SELECT DISTINCT "authors".id FROM "authors" LEFT OUTER JOIN "books" ON "books"."author_id" = "authors"."id" WHERE (name LIKE 'aa:.bb%') ORDER BY created_at DESC LIMIT 12 OFFSET 0
SQLite3::SQLException: ambiguous column name: created_at

Похоже, что при вводе aa: .bb делается дополнительный запрос для извлечения отдельного автора id_s.

Я думал, что Rails избежит всех персонажей.Это ожидаемое поведение или ошибка?

С наилучшими пожеланиями,

Питер

Ответы [ 3 ]

1 голос
/ 15 сентября 2012

Заменить

.includes(:books)

с

.preload(:books)

Это должно заставить activerecord использовать 2 запроса вместо объединения.

1 голос
/ 26 сентября 2010

Ошибка «неоднозначный столбец» обычно возникает, когда вы используете включения или объединения и не указываете, на какую таблицу вы ссылаетесь:

"name LIKE :input"

Должно быть:

"authors.name LIKE :input"

Просто «имя» является неоднозначным, если в вашей таблице книг также есть столбец с именем.

Также: посмотрите на ваш файл development.log, чтобы увидеть, как выглядит сгенерированный запрос.Это покажет вам, правильно ли вы сбежали.

0 голосов
/ 15 мая 2012

В Rails есть 2 версии include: Одна, которая создает большой запрос с объединениями (второй из двух ваших запросов и, следовательно, более вероятно, приведет к неоднозначным ссылкам на столбцы, и другая, которая избегает объединений в пользу отдельного запроса для каждой ассоциации.

Rails решает, какую стратегию использовать, исходя из того, считает ли он, что ваши условия, порядок и т. Д. Относятся к включенным таблицам (поскольку в этом случае требуется версия объединения). Где условие - это фрагмент строки, который эвристический не очень сложный - я, кажется, вспоминаю, что он просто сканирует условия для всего, что может выглядеть как столбец из другой таблицы (например, foo.bar), поэтому наличие литерала этой формы может дурак.

Вы можете либо квалифицировать имена столбцов, чтобы не имело значения, какая стратегия включает в себя, или вы можете использовать preload / eager_load вместо включений. Они ведут себя аналогично включениям, но вынуждают использовать конкретную стратегию включения, а не пытаться угадать, что является наиболее подходящим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...