[Ruby on Rails]データ登録時に重複したレコードがあった場合、登録させない

#背景
オリジナルアプリをデプロイ後、重複したデータを登録されていることに気づきます。
![スクリーンショット 0002-09-27 午前9.43.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628696/9f411b90-a3c7-8998-6ea7-8dce789a820f.png)

アプリの仕様としては、登録するレコードは重複させたくないのです。

データベースを確認すると、
登録するユーザが異なっていれば、登録できてしまうことが判明。
![スクリーンショット 0002-09-27 午前9.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628696/445d4d8a-b9a8-3095-0bea-e7170ebb30de.png)

解決にそこそこ時間がかかったので、備忘として記録します。
#問題箇所
controllerにデータ登録時の条件を設けていました。

```
require 'rubygems'
require 'mechanize'

def create
    f = (params[:wiki_url])
    
    unless 
      f.start_with?("https://ja.wikipedia.org/wiki/")
      flash[:notice] = "無効なURLが入力されたため保存できませんでした。"
      redirect_to action: 'new'
      return
    else
      agent = Mechanize.new
      page = agent.get(f) 
      page.encoding='utf-8'

以下、省略...
```

unless文には、入力したデータ（URL）に「https://ja.wikipedia.org/wiki/」
が含まれていない場合は、登録させないという条件を組んでいました。

しかし、重複したレコードがある場合、登録させないという条件が含まれていなかったため、
写真のような同じデータが登録されてしまったわけです。
#解決(結論)
以下のように書き換えて、解決しました。

```
require 'rubygems'
require 'mechanize'

  def create
    f = (params[:wiki_url])

    if not 
      f.start_with?("https://ja.wikipedia.org/wiki/")
      flash[:notice] = "無効なURLが入力されたため登録できませんでした。"
      redirect_to action: 'new'
      return
    elsif
      Company.where(page_url: "#{f}").count >= 1
      flash[:notice] = "登録済みのURLが入力されたため登録できませんでした。"
      redirect_to actionｔ: 'new'
      return
    else
      agent = Mechanize.new
      page = agent.get(f) 
      page.encoding = 'utf-8'

以下、省略...
```
teratailの記事が参考になり、解決に至りました。
:point_right:[同じ名前のデータが2件以上登録されているレコードをActiveRecordを用いて取得したいです。](https://teratail.com/questions/50832)

変更点は大きく2つです。

- unless文からif not文に変更
- **whereメソッド追加**(ココがポイント！)

##unless文からif not文に変更
[ruby unless文にelsifはないよ。。。](https://qiita.com/masaki7555/items/ca569a5c60a1cca449ca)
だそうです。

不正データの入力防止の条件に加えて、重複防止の条件を追加したい。
しかし、unless文にelsifが使えないので、
if not文に変えてelsifを追加しました。

##**whereメソッド追加**(ココがポイント！)
条件(処理)の流れは以下の通りです。

- whereメソッドで、テーブル内の条件に一致したレコードの数を取得する
- 取得したデータの数を条件にかけて１以上（データがあるか）判定する
- １以上（データがあり）ならば、受付けない

###whereメソッドで、テーブル内の条件に一致したレコードの数を取得する

.where("条件")で条件にあうレコードを取得できます。


```
モデル名.where("条件")
```

.
今回、取得するのは　Companyモデル　の　page_urlカラムです。

```
Company.where(page_url)
```

.
さらに、page_urlカラム内に入力したデータと一致するものを検索にかけたいので、
下記のように付け加えます。

```
Company.where(page_url: "#{f}")
```

.
　#{f}は変数内の文字列を表しています。
変数ｆは以下の場所で定義しており、中身はこのようになっています。

```
require 'rubygems'
require 'mechanize'

  def create
    f = (params[:wiki_url]) <=　ココです。

以下、省略...
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628696/f6962084-1b85-8a77-b876-122102ddfd16.png)

.
page_urlカラム内で検索をかけた結果、いくつあったか判定するために
countメソッドを追加します。

```
Company.where(page_url: "#{f}").count
```

###取得したデータの数を条件にかけて１以上（データがあるか）判定する

1以上、つまり入力したデータと同じURLの数を数えて１以上あるか確認します。

```
Company.where(page_url: "#{f}").count >= 1
```

###１以上（データがあり）ならば、受付けない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628696/947ba51e-4802-9910-08d0-7cd715619e56.png)

#おまけ

アプリに反映させているので、是非遊んでみてください。
[Unsung:hero](https://unsunghero.herokuapp.com/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628696/ec4da4a9-ed3a-643c-83dd-e985eec03876.png)