3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsで、"Mysql2::Error: Operand should contain 1 column(s) " エラーが出た際の対処法

Last updated at Posted at 2020-12-15

みなさんこんにちは、@ryosk7です。

状況

さくっと本題から入ります。

Mysql2::Error: Operand should contain 1 column(s)

このようなエラーが出た場合の対処法です。

状況としては、

user_ids = @current_user.sample_contents.pluck(:to_user_id)

@samples = SampleModel.where('
                              (user_id = ? and status = ?) or (user_id = ? and status is not null)',
                              user_ids, SampleModel.statuses[:open], @current_user.id)
                      .order(id: "DESC")

このようなコードを書いた際に出力されました。

解決方法

こちらです。

user_ids = @current_user.sample_contents.pluck(:to_user_id)

@samples = SampleModel.where('
                              (user_id = ? and status = ?) or (user_id = ? and status is not null)',
                              user_ids.join(","), SampleModel.statuses[:open], @current_user.id)
                      .order(id: "DESC")

違いにお気づきでしょうか。

配列をカンマで連結した文字列に変えています。

user_ids.join(",")

原因

Active Recordを利用した場合なら、user_idに配列のまま渡しても問題なく認識されますが、
SQL上でも同じようにやっていたことが原因でした。
単一の値であれば問題ないですが、複数の値であれば、リストにした文字列を渡す必要があります。

実際にはこんな感じでSQLが作られます。joinで変換したところはそのままですね。
SQLに強くないので、勉強になりました。

SELECT `sample_models`.* FROM `sample_models` WHERE ((user_id = '10,23,55' and status = 0) or (user_id = 14 and status is not null))  ORDER BY `sample_models`.`id` DESC

参考記事では、INを使ってクエリを叩いています。
同じように書くと、

user_ids = @current_user.sample_contents.pluck(:to_user_id)

@samples = SampleModel.where('
                              (user_id in (?) and status = ?) or (user_id = ? and status is not null)',
                              user_ids.join(","), SampleModel.statuses[:open], @current_user.id)
                      .order(id: "DESC")

このようになります。

SQLもINで作成されていますね。

SELECT `sample_models`.* FROM `sample_models` WHERE ((user_id in ('10,23,55') and status = 0) or (user_id = 14 and status is not null))  ORDER BY `sample_models`.`id` DESC

どちらも同じ結果が得られます。

参考

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?