今回、Herokuにデプロイする際に、「PostgreSQL」というデーターベースに変更しました。
すると、キーワードを入れて検索をしたときに以下のようなエラーが発生しました。
ActiveRecord::StatementInvalid (PG::UndefinedFunction: ERROR: operator does not exist: integer
LINE 1: ...ame FROM "products" WHERE (name like '%72%' or price like '%72%...
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
このアプリでは フォームに文字を入力すると、その値がkeywordという変数に入るようになります。
フォームに入力された値はString型として扱われます。
そしてModelで定義したscope内のwhereで条件を指定し、それにあったレコードを抽出します。
ここではあいまい検索をしており、nameカラムまたはpriceカラムの中にkeywordが含まれるレコードを取り出すという条件となります。
scope :search_by_keyword, -> (keyword) {
where("name like ? or price like ?","%#{keyword}%","%#{keyword}%") if keyword.present?
}
このアプリのデータベースではpriceというカラムはinteger型で設定していました。
まず、keyword.to_i
でinteger型に変換してから入れてみましたが、エラーの解消はできませんでした。
検索するとどうもPostgreSQLのバージョンによるものだということがわかりました。
%72%
という書き方をすると、keywordがString型かinteger型であるかは関係なく文字列となってしまうようです。
PostgreSQL8.3以前では自動型変換されていたのですが、それ以降は変換機能がなくなり、型を明示してあげる必要があります。
そこで以下のように訂正しました。
scope :search_by_keyword, -> (keyword) {
where("name like ? or price::text like ?","%#{keyword}%","%#{keyword}%") if keyword.present?
}
priceというところをprice::textと変更しました。
こうすることによってpriceはStringと認識され、検索の際に型の不一致によるエラーが出ないようになりました。