web-dev-qa-db-ja.com

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%'のように設定するにはどうすればよいですか?

115
Harry Forbess

プレースホルダーは文字列に置き換えられ、正しく処理されていません。

交換

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

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

Rails 2のconditions構文を使用する代わりに、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

注:上記では、?ではなくパラメーター構文を使用しています。プレースホルダー:これらは両方とも同じ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のバージョン

49
house9

文字列補間は機能しますが、質問で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
21
numbers1311407

ActiveRecordは、?によって参照されるパラメーターが文字列であることを認識するのに十分賢いので、単一引用符で囲みます。 couldある投稿が示唆するように、Ruby文字列補間を使用して、必要な%記号で文字列を埋めます。ただし、これによりSQLインジェクションにさらされる可能性があります(これは悪いことです)。 SQL CONCAT()関数を使用して、次のような文字列を準備することをお勧めします。

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

7
John Cleary

試して

 def self.search(search, page = 1 )
    paginate :per_page => 5, :page => page,
      :conditions => ["name LIKE  ? OR postal_code like ?", "%#{search}%","%#{search}%"],   order => 'name'
  end

詳細については、AREL条件に関する docs を参照してください。

5
tihom