【Railsエラー】DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s)...

### 始めに
投稿のいいね数の順番によってソートする機能実装中に遭遇したエラーに関するメモです。

### 前提
Ruby 2.6系
Rails 5.2系
Slim導入済
devise導入済

### 実装されている内容
##### 1.User、Post、Favoriteモデルが存在する。
#####2.favoritesテーブルを中間テーブルとして、usersテーブルとpostsテーブルが関連付けされている。

>Favoriteモデル

>```ruby:app/models/favorite.rb
class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :post
end
```

>Postモデル

>```ruby:app/models/post.rb
class Post < ApplicationRecord
  belongs_to :user
  has_many :favorites
end
```

>Userモデル

>```ruby:app/models/user.rb
class User < ApplicationRecord
  has_many :favorites
  has_many :favorite_posts, through: :favorites, source: :post
  has_many :posts
end
```

#####3.セレクトボックスフォームのコード。

>```ruby:app/views/index.html.slim
= form_with url: search_path, method: :get, local: true do |form|
  = form.select :keyword, [ 
                            ['いいねが多い順', 'likes'],
                            ['いいねが少ない順', 'dislikes'],
                          ]
  = form.submit
```

#####4.ルーティング。

>```ruby:config/routes.rb
Rails.application.routes.draw do
  #検索結果をpostsコントローラのsearchアクションへ送信
  get 'search' => 'posts#search'
  resources :posts 
end
```

#####5.条件に一致したPostを取得するpostsコントローラのsearchアクション。

>```ruby:app/controllers/posts_controller.rb
def search
    @selection = params[:keyword]
    if @selection == 'likes'
      @posts = Post.find(Favorite.group(:post_id).order('count(user_id) desc').pluck(:post_id))
    elsif @selection == 'dislikes'
      @posts = Post.find(Favorite.group(:post_id).order('count(user_id) asc').pluck(:post_id))
    end
end
```


###エラー地点

#####postsコントローラのsearchアクション内。

>```ruby:app/controllers/posts_controller.rb
def search
    @selection = params[:keyword]
    if @selection == 'likes'
      @posts = Post.find(Favorite.group(:post_id).order('count(user_id) desc').pluck(:post_id))
    elsif @selection == 'dislikes'
      @posts = Post.find(Favorite.group(:post_id).order('count(user_id) asc').pluck(:post_id))
    end
end
```

###エラー内容

>```ruby
DEPRECATION WARNING: 
Dangerous query method 
(method whose arguments are used as raw SQL) 
called with non-attribute argument(s): "count(user_id) desc". 
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().
```

読んでみると、```"count(user_id) desc"```に問題があって、```Known-safe values can be passed by wrapping them in Arel.sql().```を適用させれば解決できるとのこと。

なので、該当箇所を以下のように記述します。

```ruby:app/controllers/posts_controller.rb
def search
    @selection = params[:keyword]
    if @selection == 'likes'
      @posts = ... ...order(Arel.sql('count(user_id) desc'))... ...
    elsif @selection == 'dislikes'
      @posts = ... ...order(Arel.sql('count(user_id) asc'))... ...
    end
end
```

先ほどとの違いは、order内のcountメソッドを使った文字列をArel.sql()で囲んでるところ。

こうしなければならない理由は、Rails6.0以降SQLインジェクションの脆弱性ゆえに、第三者から勝手にパラメータを潜り込ませるのを防ぐためとかなんとか。

しかしこれで解決はできました、良かったです。

## 参考
[Rails 6 以降は order/pluck の引数に SQL 文字列を渡すことはできない (容易に対策可能)](https://qiita.com/QUANON/items/8fcc8c6cee64d246a5a6)