Rails 4 LIKE-запрос - ActiveRecord добавляет кавычки

Я пытаюсь сделать такой же запрос

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%' в конечном запросе?

Ответ 1

Ваш замещающий объект заменяется строкой, и вы не обрабатываете ее правильно.

Заменить

"name LIKE '%?%' OR postal_code LIKE '%?%'", search, search

с

"name LIKE ? OR postal_code LIKE ?", "%#{search}%", "%#{search}%"

Ответ 2

Вместо использования синтаксиса 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

Ответ 3

В то время как интерполяция строк будет работать, так как ваш вопрос задает рельсы 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

Ответ 4

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.

Ответ 5

ActiveRecord достаточно умен, чтобы знать, что параметр, обозначенный символом ?, является строкой, и поэтому он заключает его в одинарные кавычки. Вы могли бы, поскольку в одном сообщении предлагается использовать интерполяцию строк Ruby для заполнения строки с помощью символов %. Однако это может привести к SQL-инъекции (что плохо). Я бы предложил использовать функцию SQL CONCAT() для подготовки строки следующим образом:

"name LIKE CONCAT('%',?,'%') OR postal_code LIKE CONCAT('%',?,'%')", search, search)

Ответ 6

.find(:all, where: "value LIKE product_%", params: { limit: 20, page: 1 })