#背景
オリジナルアプリをデプロイ後、重複したデータを登録されていることに気づきます。
アプリの仕様としては、登録するレコードは重複させたくないのです。
データベースを確認すると、
登録するユーザが異なっていれば、登録できてしまうことが判明。
解決にそこそこ時間がかかったので、備忘として記録します。
#問題箇所
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 actiont: 'new'
return
else
agent = Mechanize.new
page = agent.get(f)
page.encoding = 'utf-8'
以下、省略...
teratailの記事が参考になり、解決に至りました。
同じ名前のデータが2件以上登録されているレコードをActiveRecordを用いて取得したいです。
変更点は大きく2つです。
- unless文からif not文に変更
- whereメソッド追加(ココがポイント!)
##unless文からif not文に変更
ruby unless文にelsifはないよ。。。
だそうです。
不正データの入力防止の条件に加えて、重複防止の条件を追加したい。
しかし、unless文にelsifが使えないので、
if not文に変えてelsifを追加しました。
##whereメソッド追加(ココがポイント!)
条件(処理)の流れは以下の通りです。
- whereメソッドで、テーブル内の条件に一致したレコードの数を取得する
- 取得したデータの数を条件にかけて1以上(データがあるか)判定する
- 1以上(データがあり)ならば、受付けない
###whereメソッドで、テーブル内の条件に一致したレコードの数を取得する
.where("条件")で条件にあうレコードを取得できます。
モデル名.where("条件")
.
今回、取得するのは Companyモデル の page_urlカラムです。
Company.where(page_url)
.
さらに、page_urlカラム内に入力したデータと一致するものを検索にかけたいので、
下記のように付け加えます。
Company.where(page_url: "#{f}")
.
#{f}は変数内の文字列を表しています。
変数fは以下の場所で定義しており、中身はこのようになっています。
require 'rubygems'
require 'mechanize'
def create
f = (params[:wiki_url]) <= ココです。
以下、省略...
.
page_urlカラム内で検索をかけた結果、いくつあったか判定するために
countメソッドを追加します。
Company.where(page_url: "#{f}").count
###取得したデータの数を条件にかけて1以上(データがあるか)判定する
1以上、つまり入力したデータと同じURLの数を数えて1以上あるか確認します。
Company.where(page_url: "#{f}").count >= 1
#おまけ
アプリに反映させているので、是非遊んでみてください。
Unsung:hero