Ответ 1
Ваш замещающий объект заменяется строкой, и вы не обрабатываете ее правильно.
Заменить
"name LIKE '%?%' OR postal_code LIKE '%?%'", search, search
с
"name LIKE ? OR postal_code LIKE ?", "%#{search}%", "%#{search}%"
Я пытаюсь сделать такой же запрос
def self.search(search, page = 1 )
paginate :per_page => 5, :page => page,
:conditions => ["name LIKE '%?%' OR postal_code like '%?%'", search, search], order => 'name'
end
Но когда он запускается, что-то добавляет кавычки, из-за чего вызывается выражение sql так
SELECT COUNT(*)
FROM "schools"
WHERE (name LIKE '%'havard'%' OR postal_code like '%'havard'%')):
Итак, вы можете увидеть мою проблему. Я использую Rails 4 и Postgres 9, оба из которых я никогда не использовал, поэтому не уверен, что это, а также вещь activerecord или, возможно, postgres.
Как я могу установить это, поэтому мне нравится '%my_search%'
в конечном запросе?
Ваш замещающий объект заменяется строкой, и вы не обрабатываете ее правильно.
Заменить
"name LIKE '%?%' OR postal_code LIKE '%?%'", search, search
с
"name LIKE ? OR postal_code LIKE ?", "%#{search}%", "%#{search}%"
Вместо использования синтаксиса conditions
из Rails 2 вместо этого используйте Rails 4 where
:
def self.search(search, page = 1 )
wildcard_search = "%#{search}%"
where("name ILIKE :search OR postal_code LIKE :search", search: wildcard_search)
.page(page)
.per_page(5)
end
ПРИМЕЧАНИЕ: в приведенном выше примере используется синтаксис параметров вместо? placeholder: эти оба должны генерировать тот же sql.
def self.search(search, page = 1 )
wildcard_search = "%#{search}%"
where("name ILIKE ? OR postal_code LIKE ?", wildcard_search, wildcard_search)
.page(page)
.per_page(5)
end
ПРИМЕЧАНИЕ: использование ILIKE
для имени - postgres регистр без учета регистра LIKE
В то время как интерполяция строк будет работать, так как ваш вопрос задает рельсы 4, вы можете использовать Arel для этого и поддерживать агностик базы данных приложений.
def self.search(query, page=1)
query = "%#{query}%"
name_match = arel_table[:name].matches(query)
postal_match = arel_table[:postal_code].matches(query)
where(name_match.or(postal_match)).page(page).per_page(5)
end
Try
def self.search(search, page = 1 )
paginate :per_page => 5, :page => page,
:conditions => ["name LIKE ? OR postal_code like ?", "%#{search}%","%#{search}%"], order => 'name'
end
Дополнительную информацию см. в docs в условиях AREL.
ActiveRecord достаточно умен, чтобы знать, что параметр, обозначенный символом ?
, является строкой, и поэтому он заключает его в одинарные кавычки. Вы могли бы, поскольку в одном сообщении предлагается использовать интерполяцию строк Ruby для заполнения строки с помощью символов %
. Однако это может привести к SQL-инъекции (что плохо). Я бы предложил использовать функцию SQL CONCAT()
для подготовки строки следующим образом:
"name LIKE CONCAT('%',?,'%') OR postal_code LIKE CONCAT('%',?,'%')", search, search)
.find(:all, where: "value LIKE product_%", params: { limit: 20, page: 1 })