joppot

コピペで絶対動く。説明を妥協しない

プログラミング

railsのscaffoldでremote formで送信後jsonを取得する

投稿日:2015年3月10日 更新日:


y89t43h

概要

みなさんこんにちはcandleです。
今回はrailsのformをremoteを使ってajaxした時に、
サーバに送った値をjavascript側で受け取る方法を紹介します。

ちなみに、私は下のサイトを参考にしました。

http://ericlondon.com/2014/01/25/ruby-on-rails-4-ajax-form.html

前提

適当なrailsプロジェクトがある

twitter bootstrap gemを使っても良いでしょう。
twiwtter bootstrap gemはデザイン名で見やすくする為に使うので、無くても構いません。
もしも、記事と同じ様に、進行したい場合は下のURLを参考にしてください。



scaffoldを作成する

scaffolを作成します。

rails g scaffold RemoteForm title:string description:text

作成されたら、マイグレーションファイルをデータベースに反映させます。

rake db:migrate

twitter bootstrap gemを入れている場合は
下のコマンドでデザインを適応させます。

rails g bootstrap:themed RemoteForms

これでscaffoldが完成しました。

フォームをajax化する

scaffoldで作成したフォームは普通にpostかputで送信してしまうので変更します。

app/views/remote_forms/_form.html.erbを開いて、以下の部分を変更しましょう。

<%= form_for @remote_form, remote: true, format: :json ,:html => { :class => 'form-horizontal remote_form' } do |f| %>

ここではリモートフォームの設定と、format jsonは多分jsonで値を返すみたいな意味だと思います。
新しくclassでremote_formというのを加えておきます。クラス名自体に意味はありません。

jsonformremote

これでフォームのリモート化は完了です。

controllerを変更する

scaffoldで作成されたcreateアクションとupdateアクションはリダイレクトかjsonで値を返すことを想定しています。

今回の場合は送られたフォームが保存に失敗しても成功しても、jsonで返してほしいので、以下の様に変更します。

app/controllers/remote_forms_controller.rbを開きます。

まずはcreateアクションの以下の部分を変更します。

respond_to do |format|
  if @remote_form.save
    format.html { redirect_to @remote_form, notice: 'Remote form was successfully created.' }
    format.json { render json: @remote_form }
  else
    format.html { render action: 'new' }
    format.json { render json: @remote_form.errors.full_messages, status: :unprocessable_entity }
  end
end

変更している箇所はform_josnの所のみです。
同じ様にupdateアクションも変更します。

respond_to do |format|
  if @remote_form.update(remote_form_params)
    format.html { redirect_to @remote_form, notice: 'Remote form was successfully updated.' }
    format.json { render json: @remote_form }
  else
    format.html { render action: 'edit' }
    format.json { render json: @remote_form.errors.full_messages, status: :unprocessable_entity }
  end
end

changetheaction

これでコントローラー側から適切なjsonを返せるようになりました。


RemoteFormのバリデーションを設定する

saveの成功と失敗をテストしたいので、バリデーションを加えます。

一番簡単なバリデーションの未入力を禁止するものを設定します。
先ほど作成したscaffoldではtitleとdescriptionがありましたが、
手っ取り早くtitileカラムにのみそれを適応させます。

app/models/remote_form.rbを開きます。
以下の内容を加えます。

validates :title, presence: true

remotemodelvalidationtitle

保存しましょう、これで、フォームからtitle未入力で値が送られてきた時はエラーを返します。

javascriptを記述して値を受け取る

最後に、javascriptを記述してフォームを送信して返ってきたjsonをうけとります。
coffeescriptで記述します。
app/assets/javascripts/remote_forms.js.coffeeを開きます。

$(document).on 'ready page:load', ->

  $(document).bind "ajaxSuccess", "form.remote_form", (event, xhr, settings) ->
    console.log xhr.responseJSON
    console.log xhr.responseJSON.title

  $(document).bind "ajaxError", "form.remote_form", (event, jqxhr, settings, exception) ->
    $.each jqxhr.responseJSON, (index, message) ->
      console.log message

説明しますと、送信が失敗したか成功したかで大きく分けます。
サーバから返ってきたjsonの値は成功したらxhr、失敗したらjqxhrに格納されています。

jsonは.resposeJSONで取得できます。
正直、これ微妙にjsonじゃない気がするけど。

上コードのconsole.logの部分はデバッグ用に表示する為に書いています。

ajaxlistenrcoffee

これで値をjsonを受け取れる様になりました。

動かして確認する

それではデモとして動かしてみましょう。
サーバを起動して

bundle exec rails s

アクセスして、
http://localhost:3000/remote_forms/
適当なデータをアップデータします。

updatetestremotetest

インスペクタを表示して、値を見てみます。
まずはエラーが取得出来るか試してみます。
titleを空にして送ってみます。

titleisblankanderror

インスペクタにerrorが出てrails側が用意したエラーが表示されています。
「Title can’t be blank」というのがそれですね。

正しい値を送ってみます。
タイトルに値をいれて送ってみます。

thisissuccessvalue

最初の結果にはjsonの中身が表示されています。
次にjsonのtitleの中身が表示されています。
いい感じですね。

まとめ

私が参考にしたサイトにはもう少し、改良されたエラー表示やデータが保存された時の表示などがありましたが、最低限上のように記述しておけば簡単なコードで動くのでぜひやってみてください。

スポンサードリンク

「為になったなぁ」と思ったら、シェアお願いします。

-プログラミング
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

ReactでFaker.jsを利用してダミーデータを生成する

概要 みなさんこんにちはcandleです。今回はFaker.jsをReactで使ってみようと思います。 Faker.jsの使用目的は様々あると思います。多くの場合はテストで使うと思うのですが、今回は簡 …

ruby on rails のckeditor gemの機能ボタンをカスタマイズする

概要 みなさんこんにちはcandleです。今回はruby on rails のckeditor gemのショートカットボタンをカスタマイズして自分が必要な機能のみを表示してみましょう。 前提 cked …

wordpress skeletonを使った開発環境の構築

はじめに みなさんこんにちはcandleです。wordpressは大変便利なのですが、いまいちgitで管理するのが難しいものです。 というのも、wordpress全体をgit管理対象にしてしまうと、w …

ruby on railsのckeditorでcarrierwaveを使って画像をアップロードする

概要 みなさんこんにちはcandleです。今回はckeditorの画像のアップロードを行ってみたいと思います。 ckeditorの画像のアップロードは公式githubにも記載されているのですが、まあや …

CakePHPでhelloworld

概要 CakePHPでプログラミングのお約束helloworldを行いましょう。 helloworldとは動作確認も含めた、一番最初に書くプログラムコードです。 だいたいはhello worldと単純 …

  • English
  • 日本語

ベンチャー企業のCTOをやってます。大学時代にプログラミングを始め、javaから入門し、C++へて、PHPへと進み、会社ではRailsを使用。自動化が大好きなプログラマー