質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

1279閲覧

【Rails】そのurl名はすでに取得されています。をAjaxでやりたい。(Twitterの@以下のように)

Romay

総合スコア40

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

1クリップ

投稿2019/04/22 22:56

編集2019/04/23 00:45

前提・実現したいこと

Railsアプリケーション作成中。
やりたいことはタイトルそのままです。
Ruby 2.4.5
Rails 4.2.8
Gem: friendly_urlを使用

いろいろ検索してみたのですが、期待する記事を見つけることができなかったのでこちらでヒントをいただけると嬉しいです。

(追記)
Twitterの@以下が一意制約で固有のものであるのや、質問箱でオリジナルのURLを設定できるのと同じような実装を考えています。

期待する動作は以下の通りです。

  1. ユーザー情報編集画面でユーザーがオリジナルのfriendly_urlを設定
  2. すでに取得されている場合、入力と同時にAjaxでアラートを表示

モデル側に一意制約(ユニーク制約)バリデーションを設定しているのですが、入力し送信する前にアラートを出したいです。
このアラートは、ヘッダー部分に表示されるものではなく、入力フォームの下に赤文字で表示されるようなイメージです。
というのも、編集画面をモーダルで行なっているため、送信ボタン押下後のアラート表示の方が難しいのではと思うからです。
もしこちらの方がかんたんにできそうということであればご教授いただけると嬉しいです。

該当のソースコード

モデルでuniqueness: trueの設定をしています。

モデル
user.rb

ruby

1 2 #friendly_url 3 include FriendlyId 4 friendly_id :friendly_url 5 6 validates :friendly_url, length: { in: 3..20 }, 7 uniqueness: true, #一意性 8 format: { with: /\A[\w@-]*[A-Za-z][\w@-]*\z/ }, 9 # on: :friendly_url_user #登録時に入力必要なし 10 allow_nil: true #無入力許可

ユーザー情報編集画面のモーダル上にあるフォームです。
edit.html.erb

ruby

1<%= form_for @user do |f| %> 2 <div class="modal-body"> 3 <label> 4 <span>アイコン画像 5 <%= f.file_field :avatar ,:style=>"display:none;" , id: 'avatar_img' %> 6 </span> 7 <div > 8 <img src="#"/> 9 <%= image_tag(@user.avatar(:medium), :size => "70x70") %> 10 </div> 11 </label> 12 <ul> 13 <li> ユーザー名<%= f.text_field :nickname, placeholder: "ニックネーム(必須)",:required => true %></li> 14 <li> URL (3~20文字英数字)><%= f.text_field :friendly_url, placeholder: "URLを設定(英数字3-20文字)(必須)", :required => true %></li> 15 <!--ここにエラーメッセージをAjaxで表示したい--> 16 </ul> 17 </div> 18 <div class="modal-footer"> 19 <%= f.submit "完了", class: "btn" %> 20 </div> 21 <% end %> 22

試したこと

javascriptの知識が薄いのと、入力と同時にDBから情報をとってきて一意制約を確認するというフローをどう実装するのかイメージできていません。
また参考になりそうなサイトや記事などあれば教えていただけると嬉しいです。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/04/23 00:25 編集

セキュリティ上気になる点なのでこちらで確認させていただきますが、 「そのユーザー名はすでに取得されています」とストレートに出してしまうと、悪意あるユーザーに対して「このユーザーは存在する」と情報を与えてしまうことになりませんか?「ログインしたユーザーしか使えない」仕組みなのであればなおさら避けられたほうが良さそうです。
Romay

2019/04/23 00:28

コメントありがとうございます。タイトルは分かりやすくするため「ユーザー名」と表記していますが、実際の実装は、「一意制約のあるURLを設定する」ことです。Twitterの@以下が一意制約なことや質問箱のオリジナルURLの設定と同じようなものだと考えていただけると想像しやすいかと思います。また、このURLはログイン時には使用いたしません。質問内容が分かりにくくて申し訳ありません。
m.ts10806

2019/04/23 00:30

了解です。少し二度手間になってしまいますが、あとから見たときにそのあたりが分かりやすいよう(誤解を与えにくいように)質問内容を調整いただけますか?
Romay

2019/04/23 00:42

承知しました。ご意見いただきありがとうございます!
guest

回答2

0

ベストアンサー

Rubyについては明るいわけではないので考え方、やり方の案だけ

・入力欄のフォーカスアウトでイベントを発火で入力値を取得
よく使われるのはblurです。

html

1<input type="text" name="friendly_url" id="friendly_url">

※簡潔に書くためjQueryで記述しています

js

1$('#friendly_url').on('blur',function(){ 2 let f_url = $(this).val(); 3});

・入力値をajaxで送信
Rubyによる扱いは詳しくないですが、基本はform送信と同じくPOST,GETなどで送信した内容を連想配列にして送信します。 参考:Rails で JavaScript を使用する
・入力値を受け取り、DB問い合わせ
※friendly_urlというのがどういうものか分かっていませんが、要は「入力値で検索する」ですね
・取得できた=使われている 取得できない=使われていない として、Ajaxのレスポンスとする(JSON形式がよく使われます)
・レスポンスを受け取ってJavaScript側で結果を表示

JavaScript側だけ書くとこんな感じ。
※Railsでは表記などは違うかもしれませんが、イメージだけ持ってもらえたらと

js

1$(function(){ 2 $('#friendly_url').on('blur',function(){ 3 $(this).next('span.error').remove(); 4 $(this).removeClass('input_error'); 5 let f_url = $(this).val(); 6 if(f_url == ""){ 7 $(this).addClass('input_error'); 8 $(this).after('<span class="error">入力してください</span>'); 9 $(this).focus(); 10 return; 11 } 12 $.ajax({ 13 type:'POST', 14 url:'check', 15 data:{url:f_url}, 16 dataType:'json', 17 }).done(function(data, status, xhr) { 18 if(status === "success"){ 19 if(data.isduplicated){ 20 $('#friendly_url').addClass('input_error'); 21 $('#friendly_url').after('<span class="error">既に利用されています</span>'); 22 $('#friendly_url').focus(); 23 } 24 } 25 }).fail(function(xhr, status, error) { 26 console.log(xhr); 27 }); 28 }); 29 });

※サーバーサイドでは下記のようなJSONを作って返した想定です

JSON

1{ 2 "isduplicated": true 3}

投稿2019/04/23 01:58

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Romay

2019/04/23 22:01

>入力欄のフォーカスアウトでイベントを発火で入力値を取得 >取得できた=使われている 取得できない=使われていない として、Ajaxのレスポンスとする 大変勉強になりました! DB問い合わせの箇所について少し質問させてください。 https://localhost/something からユーザーがsomethingをaiueoに変えたいとします。 この場合、https://localhost/aiueo が存在するかどうか調べるのか、 friendly_urlのカラムにaiueoが存在するのかを調べるのかどちらなのでしょうか。 検索したいfriendly_urlカラムは、Userテーブルにあります。
m.ts10806

2019/04/23 23:20

サーバーサイドの言語の基本としてはリクエストを受け取って処理を行うわけですからURLを叩いてレスポンスが返ってくるか確認することにあまり意味はありません。結局ブラウザからそのURLを実行した際にはaiueoというリクエストを受け取ってDBに問い合わせをしてから表示する情報を判断しているわけですよね? で、あればDB問合せのみで対応しましょう。 情報をもとにURLが生成されるわけではなく、URLをもとに情報が決定します
Romay

2019/04/26 20:59

なるほど、大変勉強になりました。色々試してみたもののうまくいってない部分もあり、またRailsのコードと関係してくるところもあるためこの投稿とは別に質問させていただきます。回答いただきありがとうございました。
m.ts10806

2019/04/26 23:54

ヒントになったようで何よりです
guest

0

ajaxでapiに対して所定のデータを投げて、その真偽で判断すればよいでしょう

javascript

1<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 2<script> 3$(function(){ 4 $('#check').on('click',function(){ 5 $.ajax({ 6 url:"api.txt", 7 dataType:"json", 8 data:{user:$('[name=user]').val()}, 9 cache:false, 10 }).done(function(data){ 11 console.log(data); 12 if(data) alert('そのurl名はすでに取得されています'); 13 }); 14 }); 15}); 16</script> 17<input type="text" name="user" value="hoge"> 18<input type="button" value="check" id="check">

api.txtには"true"か"false"を記載してください
"true"とかけばalertを出します、"false"とかけばalertはでません。
あとはapi.txtのところをrubyでジャッジしてtrue/falseの文字を返すようにすればよいでしょう

投稿2019/04/23 01:56

yambejp

総合スコア114863

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問