【フリマアプリ】商品詳細ページのコメント機能（第１回）〜モデル、マイグレーション編〜

　某スクールにおいて、チーム開発で、フリーマーケットアプリを作成中であり、使用した技術について公開しています。
※初学者のため、ミスや認識違いが多々あると思いますがご了承ください。

# 商品詳細ページにコメント機能を実装しました。
全部で7回に分けて記事を投稿しています。

    |内容             |                  url   |
|:-----------------|------------------:|:-----------------------------:|
| 第１回             |       モデル、マイグレーション編 |    https://qiita.com/sho_U/items/03108801146e65d58413 |
| 第２回         |           ルーティング編 |     https://qiita.com/sho_U/items/5c829b3060be2cce919a |
| 第３回|コントローラー編|https://qiita.com/sho_U/items/8528f336cf0d470cd719|
|第４.1回|ヴュー編(一覧表示）|https://qiita.com/sho_U/items/6190562270c722956547|
|第４.2回|ヴュー編(インプットフォーム）|https://qiita.com/sho_U/items/67c2ede4fc6c605283e2|
|第５回|jquery編|https://qiita.com/sho_U/items/d72b60114f76380d05f6|
|第6回|ajax編|https://qiita.com/sho_U/items/caed9b1471e63d43dd3a|

〜コード全文〜https://qiita.com/sho_U/items/310ac5b653bdfcb99a2c

## 前提条件
1. 商品の各データーに紐づく商品詳細ページが完成している。
2. 商品を管理するItemモデル、ユーザーを管理するUserモデルが存在している。


## 実装要件
- サーバーサイド
 - 閲覧者が商品に対する自由にコメントできる。
 - 商品出品者は全てのコメントを**「仮削除」**することができる。
 - 出品者は仮削除したコメントを**「復元」「完全削除」**することができる。
- マークアップ
 - **コメント投稿、仮削除、復元、完全削除**は**非同期通信**により即時反映される。
 - ログイン中のユーザー自身の投稿と、その他のユーザーの投稿に差異をつける。
 - 出品者のコメントとには、名前の下に**「出品者」**の表示を設ける。
 - 出品者の画面には、コメント**「削除ボタン」**がついている。
 - 出品者が削除した場合、コメントの内容には、**「出品者によりコメントが削除されました」**と表示される。
 - 出品者の画面には、削除したコメントには、**「復元ボタン」**と**「完全削除ボタン」**が現れる。

## 動作イメージ

####非出品者の投稿
![2eb69c9a9b4362324d1b494ddadc67ec.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/4af712c0-7b55-2304-0925-1c69b4f98847.gif)


#### 出品者による　仮削除　→　復元　→　完全削除
![ef150ed44807ba858b976bd544b7a672 (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/007cc98c-0cb7-9042-d80b-60110c3b0e27.gif)



##モデルについて
コメントは、一つの商品に対し、複数作成されるため**「Itemモデル」**とは別に**「Commentモデル」**として管理することとしました。
コメントは、商品とユーザーにそれぞれ結びついています。
そこで、アソシエーションを組む事にします。

1. Itemモデルと、Commentモデルのアソシエーションについて
　Item（商品）は、複数のコメントを持っています。逆にComment（コメント）は１つのItemにのみ、紐づいています。　よって、Commentが、Itemに所属する**多対１**の関係となります。

2. Userモデルと、Commentモデルのアソシエーションについて
 User（ユーザー）は、複数のCommentを持っています。逆にCommentは１つのUserにのみ、紐づいています。　よって、Commentが、Userに所属する**多対１**の関係となります。

上記を踏まえてアソシエーションは以下の通りとしました。

```ruby:comment.rb
class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :item
end
```

```ruby:item.rb
class Item < ApplicationRecord
  has_many :comments, dependent: :destroy

  belongs_to :seller, class_name: "User" , optional: true,foreign_key: "seller_id"
  belongs_to :buyer, class_name: "User", optional: true,foreign_key: "buyer_id"
  belongs_to :auction, class_name: "User", optional: true,foreign_key: "auction_id"

end

# dependent: :destroy
# ↑この記載により、商品が削除された場合、紐づくコメントも連動して削除されるようになります。
```

また、本記事の趣旨とははずれるのですが、Itemは、延べ3人のUserと結びついています。
Itemには、出品者、購入者、取引中ユーザーと結びついています。そこで、上記のようなアソシエーションを組んでいます。

これで例えば、商品の出品者を取得したい場合は、

``` 
@item.seller
```
<img width="975" alt="267d5fa313cc2328557739a3cc7ed913.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/625e17e5-2e4c-4ec7-d4a6-3e693ffbad66.png">
上記のような記載で取得することが可能となります。

```ruby:user.rb
class User < ApplicationRecord
    has_many :comments, dependent: :destroy
end
```
商品とユーザーの関係については下記の投稿を参照ください。
※鋭意作成中

##マイグレーションについて

```ruby:
class CreateComments < ActiveRecord::Migration[5.0]
  def change
    create_table :comments do |t|
      t.references :item, null: false, foreign_key: true
      t.references :user, null: false, foreign_key: true
      t.integer :delete_check,default: 0
      t.string :comment
      t.timestamps
    end
  end
end
```
コメントの内容は**「commentカラム」**に保存します。あとは、itemと、userに対する外部キーをもうけました。
**「delete_check」**というカラムは、後ほど説明いたします。　**default: 0**　と言う記載で、初期値として**0**を与えています。

以上が、モデルとマイグレーションについての説明となります。

###次回（第２回）は、ルーティング編となります。
https://qiita.com/sho_U/items/5c829b3060be2cce919a