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

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

ただいまの
回答率

90.54%

  • JavaScript

    19937questions

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

  • Ruby

    9233questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    8658questions

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

  • Ruby on Rails 4

    2535questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

  • Ajax

    1293questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Railsアプリ、reactでPOSTした内容を表示したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 944

solt0723

score 57

前提・実現したいこと

RailsアプリケーションにReactを導入し、その中でAjaxを利用して投稿をPOSTする機能を作成しています。
POSTする部分までは作成できたのですが、さらに、POST後にPOSTした内容を表示する機能を作成したいと思っています。

Rails 4.2.2   
Ruby 2.0.0   
React
Ajax
で開発をしています。

実装がうまくいかない箇所

イメージ説明

このスクリーンショット内の、テキストフォームの「POST」というテキストを
POSTボタンがクリックされた後にテキストフォームの上あたりに表示したいのですが
POST成功後、表示する部分を実装できずにいます。

現状では、POSTボタンタップ後、下記のようなサーバーログが表示され
POST自体は成功しています。

Started POST "/microposts" for ::1 at 2017-01-15 17:20:21 +0900
Processing by MicropostsController#create as */*
  Parameters: {"micropost"=>{"content"=>"POST"}}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE 

中略

Completed 302 Found in 16ms (ActiveRecord: 9.5ms)

ただ、上記のように投稿後に表示する部分がうまくいかず、下記のスクリーンショットのような表示となってしまいます。
本当は、ここでテキストフォームと「MessageBox」というテキストの間に投稿した内容を表示したいです!!

イメージ説明

該当のソースコード

reactで投稿する実装は、下記のサイトを参考にしています
http://ruby-rails.hatenadiary.com/entry/20151122/1448118932

まず、テキストフォームを生成して、POSTする内容を受け取るコードは次のようになっています。

var MessageForm = React.createClass({
  handleSubmit: function(event) {
    event.preventDefault();
    var user = this.refs.user.value.trim();
    // 親コンポーネントのMessageBocのイベントを呼び出す
    this.props.onMessageSubmit( user );
    // フォームの内容を削除
    this.refs.user.value = '';
  },

 // 投稿用のフォームを作成して、'user'として内容を受け取る
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Title" ref='user'/>
        <input type="submit" value="Post" />
      </form>
    );
  }
});

次に、上記のコードから投稿する内容を受取、AjaxでPOSTするコードが以下のようになっています。

var MessageBox = React.createClass({
  getInitialState: function() {
    // isLoading = true : ロード中を表示
    return { messages: [], isLoading: true };
  },

...中略

 // 投稿の内容をAjaxでPOST
  handleMessageSubmit: function(message) {
    $.ajax({
      url: 'microposts',
      datatype: 'json',
      type: 'POST',
      beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
      data: {
        micropost: { content: message }
      },
      success: function(message) {
        var newMessages = this.state.messages.concat(message);
        this.setState({ messages: newMessages });
      }.bind(this),
      error: function(_xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },

  render: function() {
    var messageItems = this.state.messages.map(function(message) {
      return (
        <MessageItem key={message.id} message={message}/>
      );
    });

  // ボタンがクリックされた時に、投稿する内容を受け取ってhandleMessageSubmitに渡す
    return (
      <div>
        <h1>Message Box</h1>
        <div className="messageBox">
          {messageItems}
          <MessageForm onMessageSubmit={this.handleMessageSubmit}/>
        </div>
      </div>
    );
  }
});

最後に、投稿した内容を表示するためのコードが下記のようになっています。

var MessageItem = React.createClass ({
  render: function() {
    return (
      <div className="message">
        <h2 className="messageUser">{this.props.message.user}</h2>
      </div>
    );
  }
});


必要な情報などあれば、いっていただけると助かります。

追記

編集依頼にいただいた内容ですが、handleMessageSubmitが実行された際には、下記のサーバーログが残っていました。

Started POST "/microposts" for ::1 at 2017-01-16 19:48:46 +0900
Processing by MicropostsController#create as */*
  Parameters: {"micropost"=>{"content"=>"サンプル"}}
  User Load (1.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 103]]
   (0.5ms)  begin transaction
  SQL (3.0ms)  INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["content", "サンプル"], ["user_id", 103], ["created_at", "2017-01-16 10:48:46.294594"], ["updated_at", "2017-01-16 10:48:46.294594"]]
   (0.9ms)  commit transaction
Redirected to http://localhost:3000/home
Completed 302 Found in 59ms (ActiveRecord: 5.5ms)

302が返ってきているようなのですが、これが問題なのでしょうか、、

もう1点、MessageItemの動きを調べている時に気づいた点があったので記載します。

まず、MessageItemが呼び出されていないかも、と思ったので、MessageItemメソッドの中身を

var MessageItem = React.createClass ({
  render: function() {
    return (
      <div className="message">
        <h2 className="messageUser">{this.props.message.user}</h2>
      </div>
    );
  }
});


上記から下記に書き換えてみました。
「サンプル」というテキストを追加しています。

var MessageItem = React.createClass ({
  render: function() {
    return (
      <div className="message">
        <h2 className="messageUser">サンプル{this.props.message.user}</h2>
      </div>
    );
  }
});

イメージ説明

その後、実際に動かしてみると、Postボタンをタップする前には
上記のスクショのようになっているところ、
Postボタンタップ後に下記のスクショのように
「サンプル」というテキストが表示されました。

イメージ説明

これでMessageItemが呼び出されていることは分かったのですが、
投稿した内容が表示されないというのは
MessageItem内の{this.props.message.user}の部分に
データがうまく渡っていないのでしょうか。。。

とりとめのない追記で申し訳ありませんが、見ていただけると大変助かります。

さらに追記 01/17

コメントにいただいたように、success:の中でconsole.log(message)を記載してchromeで確認をしました。

htmlが吐き出されているようで、かなり長いログになっていました。。
※あまりに長いので、一部省略しています。

<!DOCTYPE html>
<html>
  <head>
    <title>Ruby on Rails Tutorial Sample App</title>
    <link rel="stylesheet" media="all" href="/assets/account_activations.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="true" />

中略

  <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
  </script>
<![endif]-->

  </head>
  <body style="color: rgb(27, 29, 34)">
    <header class="navbar navbar-inverse">
  <div class="container" style="margin-top: 100px;">
    <a id="logo" href="/home">sample app</a>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="/home">Home</a></li>
        <li><a href="/help">Help</a></li>
          <li><a href="/users">Users</a></li>
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
              Account <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
              <li><a href="/users/103">Profile</a></li>
              <li><a href="#">Settings</a></li>
              <li class="divider"></li>
              <li>
                <a rel="nofollow" data-method="delete" href="/logout">Log out</a>
              </li>
            </ul>
          </li>
      </ul>
    </nav>
  </div>
</header>

    <div class="landing">
      <div class="alert alert-success">Micropost created!</div>
        <div class="container">
    <div class="row col-md-12">
      <h1>
        <section class="user_info">
          <a href="/users/103"><img alt="example_sample@example.com" class="gravatar" src="https://secure.gravatar.com/avatar/1a51ab8ceafa101e9b36619b6c9b277d?s=80" /></a>
<h1>example_sample@example.com</h1>
<span><a href="/users/103">view my profile</a></span>
<span>84 microposts</span>

          <div class="stats">
  <a href="/users/103/following">
    <a id="following" class="stat">
      1
      following
    </a>
  </a>
  <a href="/users/103/followers">
    <a id="followers" class="stat">
      0
      followers
    </a>
  </a>

中略
        </section>
        <div data-react-class="MessageBox" data-react-props="{}"></div>
      </div>
    </div>
  </div>

      <footer class="footer">
  <small>
    The <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
    by <a href="http://www.michaelhartl.com/">Michael Hartl</a>
  </small>
  <nav>
    <ul>
      <li><a href="/about">About</a></li>
      <li><a href="/contact">Contact</a></li>
      <li><a href="http://news.railstutorial.org/">News</a></li>
    </ul>
  </nav>
</footer>

      <pre class="debug_dump">--- !ruby/hash:ActionController::Parameters
controller: static_pages
action: home
</pre>
    </div>
  </body>
</html>

また、chromeのconsoleをみると、もう一つエラーが表示されていました。

micropost.self-560a548….js?body=1:19 undefined "parsererror" "SyntaxError: Unexpected token < in JSON at position 0"


コードの該当部分は、POSTのajax内のerror:、下記の部分のようです。

    console.error(this.props.url, status, err.toString());

よろしくお願いします。

さらにさらに追記 1/17(2)

micropostsのcontrollerは下記のようになっています。

class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy, :show]
  before_action :set_micropost, only: [:destroy, :show]

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to home_path
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end

  def destroy
    @micropost.destroy
    flash[:success] = "Micropost deleted"
    redirect_to request.referrer || home_path
  end

  def show
    messages = Micropost.find(params[:id])
    render json: messages
  end

  private

    def micropost_params
      params.require(:micropost).permit(:content, :picture)
    end

    def set_micropost
      @micropost = current_user.microposts.find_by(id: params[:id])
      redirect_to home_path if @micropost.nil?
    end
end
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • solt0723

    2017/01/17 20:28

    丁寧にコメントありがとうございます!ステータスコードの件も大変参考になりました。console.logでの出力結果を、さらに追記として記載しました。まだ、内容を詳しく見れていないのですが、HTMLが吐き出されているようで、仰る通りthis.props.message.user に意図した値は入っていないようでした。

    キャンセル

  • d-mato

    2017/01/17 20:49 編集

    最初にコメントしたように、やはりRailsからの応答がおかしいですね。MicropostsControllerのソースも見せてもらえますか?jsonを返すように修正する必要がありそうです。

    キャンセル

  • solt0723

    2017/01/17 21:18

    microposts_controller.rbを追記しました。jsonを返す、、!たしかにそういった処理を追記していなかったです。 render json: message などをcreateアクションに追記すればいいでしょうか?

    キャンセル

回答 1

checkベストアンサー

+2

if @micropost.saveの中のredirect_to home_pathrender json: @micropostに書き換えることで、作成成功時にjsonを返すようになります。

エラー処理もするならelse以下も同様に修正が必要ですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/17 22:13

    回答いただいたように、redirect_to home_pathをrender json: @micropostにすることで、解決しました!何回もついか改修依頼していただき、ありがとうございます。加えてですが、MessageItem内のthis.props.message.userのuserが正しくなかったようで、this.props.message.contentとすることで、POSTした内容が表示されるようになりました。

    キャンセル

同じタグがついた質問を見る

  • JavaScript

    19937questions

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

  • Ruby

    9233questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    8658questions

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

  • Ruby on Rails 4

    2535questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

  • Ajax

    1293questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。