LoginSignup
2
0

More than 3 years have passed since last update.

Rails6 のちょい足しな新機能を試す105(カラム名編)

Posted at

はじめに

Rails 6 に追加された新機能を試す第105段。 今回は、 カラム名編です。
Rails 6 では、 pluckorder で指定するカラムの書き方が "table"."column" でも Arel.sql() で囲いなさいという警告が出なくなりました。
Arel.sql() で囲っても囲わなくても結果としては変わらないことが理由のようです。
この変更に伴い、 Rails 5.2.3 で出ていたRails 6.0 では禁止となると DEPRECATION WARNING が出ていたところが、Rails 6.0 で禁止にならず、Rails 6.1 に持ち越されました。

(注意: Rails 6.0.1 がリリースされましたが、動作確認時点での最新版は、Rails 6.0.0 でした。 Rails 6.0.1 では未確認です :bow:)

Ruby 2.6.5, Rails 6.0.0, Rails 5.2.3 で確認しました。
また、データベースは、 PostgreSQL 12.0 を使っています。

$ rails --version
Rails 6.0.0

今回は、User モデルを作って、 rails console で確認します。

Rails プロジェクトを作る

$ rails new rails_sandbox
cd rails_sandbox

User のモデルを作成する

$ bin/rails g model User name

データベースのマイグレーションを実行する

$ bin/rails db:create db:migrate

rails console で確認します。

User.order の引数を変更して確認します。

name を指定する

name を指定したときは、警告は出ません。

irb(main):001:0> User.order("name")
  User Load (0.9ms)  SELECT "users".* FROM "users" ORDER BY name LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

users.name を指定する

users.name を指定したときは、警告は出ません。

irb(main):002:0> User.order("users.name")
  User Load (0.9ms)  SELECT "users".* FROM "users" ORDER BY users.name LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

"users"."name" を指定する

"users"."name" を指定したときも、警告は出ません。

irb(main):003:0> User.order('"users"."name"')
  User Load (0.9ms)  SELECT "users".* FROM "users" ORDER BY "users"."name" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

name /* comment */ を指定する

name /* comment */ を指定したときは、 DEPRECATION WARNING が出ます。

irb(main):006:0> User.order("name /* comment */")
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "name /* comment */". Non-attribute arguments will be disallowed in Rails 6.1. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql(). (called from irb_binding at (irb):6)
  User Load (0.8ms)  SELECT "users".* FROM "users" ORDER BY name /* comment */ LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

Rails 5 では

Rails 5.2.3 では、 name /* comment */ を指定したときの他、 "users"."name" のときも DEPRECATION WARNING が表示されます。

irb(main):003:0> User.order('"users"."name"')
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "\"users\".\"name\"". Non-attribute arguments will be disallowed in Rails 6.0. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql(). (called from irb_binding at (irb):3)
  User Load (0.8ms)  SELECT  "users".* FROM "users" ORDER BY "users"."name" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

Arel.sql() で囲ってみても結果的に実行されるSQL は、警告が出ていたときと何ら変りありません。

irb(main):005:0> User.order(Arel.sql('"users"."name"'))
  User Load (0.9ms)  SELECT  "users".* FROM "users" ORDER BY "users"."name" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try105_disallow_row_sql

参考情報

2
0
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
2
0