Rails 4 LIKE query-ActiveRecord добавляет кавычки

Я пытаюсь сделать подобный запрос, как so

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

6 ответов


ваш заполнитель заменяется строкой, и вы не воспринимает это правильно.

заменить

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

С

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

вместо conditions синтаксис из Rails 2, Используйте Rails 4's 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

Примечание: выше используется синтаксис параметра вместо ? заполнитель: они оба должны генерировать один и тот же 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


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

попробовать

 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 на условиях АРЕЛА для получения дополнительной информации.


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 })