きっかけ
SNS的なWebアプリを作成しており、投稿一覧ページで最新の投稿を一番上に表示させるために、postテーブルのcreated_atをキーにORDERクエリを実行したところ下記のエラーが発生した。
ブラウザ.web
Mysql2::Error: Expression #1 of
ORDER BY clause is not in SELECT list, references column
'app_name_development.posts.created_at' which is not in SELECT list;this is incompatible with
DISTINCT: SELECT DISTINCT posts.id FROM `posts` WHERE `posts`.`body` LIKE '%うま%' ORDER BY `posts`.`created_at` DESC
posts_controller.rb
@posts = @q.result(distinct: true).order(created_at: :desc)
環境
ruby:2.7.2
Rails 5.2.5
mysql:5.7
開発環境: Docker
原因
どうやらMySQL5.7からsql_mode,'ONLY_FULL_GROUP_BY
という設定が追加されたことが原因となっているらしい。
解決方法
解決方法としては2つあるらしい。
解決方法1
影響するSQL文を変える
解決方法2
MySQLの設定を変える
今回の場合は投稿の一覧の順番を変えるだけだったので、created_atではなくテーブルのidでORDERクエリを使うことで同じような動きはしてくれたが、今後のことも考えてMySQLの設定を変えることにしました。
こうしたらいけた
docker-compose.yml
db:
image: mysql:5.7
# ONLY_FULL_GROUP_BYを回避するために追加
command: #追加
- --sql-mode=NO_ENGINE_SUBSTITUTION #追加
ビルドするとORDERクエリを無事に使えるようになった!!!
参考URL