Rails7 find と where では結果の型が異なる件

# はじめに
みなさん、こんにちは。**torihazi**です。
今回はタイトルの件について書いていこうと思います。
ちなみに初心者です。
間違いがないよう最善は尽くしていますが、何かあれば指摘をお願いいたします。

# 環境について
```
ruby 3.2.1
rails 7.0.6
```

# 結論
- `find`ならArray オブジェクト が
- `where`ならActiveRecord::Relation オブジェクトで

返ってくるよということ。
例えば下記のような時。
```
id = [1]
@hoge_find = Hoge.find(id)
@hoge_where = Hoge.where(id: id)
```

これをviewのlink_toで参照しようとしたときに
```
= link_to hoge_path(@hoge_find) 
=> /hoge/1
= link_to hoge_path(@hoge_where) 
=> /hoge%23%3CHoge::ActiveRecord_Relation:・・・・・・"
```
生成されるURLが違ってくる。


# なんで気づいたか
今、XクローンのDM機能(ユーザ同士の1対1チャット)を作っています。
Userにdevise gem は使っています。
![スクリーンショット 2024-05-19 9.47.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567812/b71def71-362b-4871-a1c3-03b7a2456d1d.png)

その時に
> ログインユーザがすでにDMし合っているユーザの詳細画面において
> 表示されているDMアイコンをクリックした際にそのユーザとのDMページに遷移する

という処理を書いていました。
処理イメージだと次の感じです。
1. user1でログインし、相互フォローしているuser8の詳細ページに遷移します
1. そのページにおいてDMアイコンをクリックします
![スクリーンショット 2024-05-19 10.00.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567812/a4aaa413-1a54-ff31-48be-1ac1fa25403f.png)
1. するとDMしていなければDMに関するものをcreateしてから、あればそのままDMのページに遷移します。(urlだと/users/8/conversations/2 のような感じ)
![スクリーンショット 2024-05-19 10.20.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567812/8fac0f05-046f-745b-a378-853ff3bf5a82.png)


---

この2番において
> すでにDMをし合っているか

ということを判別するために下記のロジックをUser.rbに作りました。
```Ruby:user.rb
class User < ApplicationRecord
~~~
  has_many :participants, dependent: :destroy
~~~
  def find_conversation_with(other_user)
    id = ( participants.pluck(:conversation_id) ) &
         ( other_user.participants.pluck(:conversation_id) )
    id.any? ? Conversation.where(id: id) : nil 
  end
end
```
この結果をusers_controller.rbにおいて次のように使用しました。
```Ruby:users_controller.rb
  def show
  ・・・
    @conversation = current_user.find_conversation_with(@user)
　　　　・・・
  end
```

そしてビュー側で次のように表示を分けました。
```Ruby:users/show.html.slim
~~~
- if @conversation
    = link_to user_conversation_path(@user, @conversation), class: "btn btn-outline-dark rounded-circle" do 
    i.bi.bi-envelope-plus
- else    
  = link_to user_conversations_path(@user), data: { "turbo-method": :post }, class: "btn btn-outline-dark rounded-circle" do 
    i.bi.bi-envelope-plus
```

この時ビュー側で`/users/8/conversations/2`というlinkが生成されるのかと思いきや
恐ろしいurlが生成されていました。
![スクリーンショット 2024-05-19 10.18.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567812/030d0c10-8bf7-7459-04d4-19fdc8d56a28.png)

この原因は
> `where`ならActiveRecord::Relation オブジェクトで

だからです。

そのため解決策としてはいろいろあるかと思いますが、自分は次のように`find`で行いました。
```diff:user.rb
class User < ApplicationRecord
~~~
  has_many :participants, dependent: :destroy
~~~
  def find_conversation_with(other_user)
    id = ( participants.pluck(:conversation_id) ) &
         ( other_user.participants.pluck(:conversation_id) )
-    id.any? ? Conversation.where(id: id) : nil 
+    id.any? ? Conversation.find(id) : nil 
  end
end
```
こうすれば urlも次のように`/users/1/conversations/1`のようになります。

![スクリーンショット 2024-05-19 16.26.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567812/a4fd7d3f-6b6e-e1c3-e66d-531903ee904d.png)

# 終わりに
なんとなくで使い分けていましたが、このような違いがありました。

これからも学習を続けていきたいと思います。

ただ今回のDMし合っているかの判別は `1対1のDMまでしかできないアプリ`しか使えないと思います。

グループチャットを考えたら機能しないかと思います。

そのためその時はその時考えようかと思います。

あとコードレビューもしていただいていないため、修正入るかもです。

そしたらその時直します。