🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

Ruby on Rails

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

Q&A

解決済

1回答

647閲覧

Rails5.2.3 + Vue.jsでJSON形式のデータをPOSTできない

hitsujimon1984

総合スコア5

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

Ruby on Rails

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

0グッド

1クリップ

投稿2019/09/09 01:49

編集2019/09/09 06:29

Vue.jsでJSON形式のデータをPOSTしたい

現在Rails5.2.3 + Vue.js でタスク一覧を取得するTODOアプリを作成しています。
以下のサイトを参考に作っています。
Vue.jsとRailsでTODOアプリのチュートリアルみたいなものを作ってみた

その際、JSON形式でデータのやり取りを行なっています。
そこで以下のような流れを行いました

  • db/seeds.rb に初期データを記述し、コンソールで $rails db:seedを実行し初期データを流し込む
  • JSON形式のデータがデータベースに取り込まれているか,curlコマンドで確認する[OK]

-- 1. bin/server でrailsサーバーを起動する(http://localhost:5000)
-- 2. $ curl localhost:5000/api/tasksでAPIの確認をする

ここまでは問題なくできたのですが、次の段階として
「curlコマンドでJSON形式のデータをPOSTする際に、エラーが発生」
してしまいうまくいきません。
下記にその詳細を記します。

どのコードが原因でエラーが起きているのかさっぱりわからなくなってしまいました。
controllerが原因かと思ったのですが。
ご回答、ご教授よろしくお願いいたします。

curlコマンドでJSON形式のデータをPOSTできない

ターミナル> $ curl -X POST localhost:5000/api/tasks -d 'task[name]=fugafuga'

エラーメッセージ (上記コマンドの結果、以下のメッセージがターミナルに出力される(javascriptの中身??)) ~~ // Push the error page body upwards the size of the console. // // While, I wouldn't like to do that on every custom page (so I don't screw // user's layouts), I think a lot of developers want to see all of the content // on the default Rails error page. // // Since it's quite special as is now, being a bit more special in the name of // better user experience, won't hurt. document.addEventListener('DOMContentLoaded', function() { var consoleElement = document.getElementById('console'); var resizerElement = consoleElement.getElementsByClassName('resizer')[0]; var containerElement = document.getElementById('container'); function setContainerElementBottomMargin(pixels) { containerElement.style.marginBottom = pixels + 'px'; } var currentConsoleElementHeight = consoleElement.offsetHeight; setContainerElementBottomMargin(currentConsoleElementHeight); resizerElement.addEventListener('mousedown', function(event) { function recordConsoleElementHeight(event) { resizerElement.removeEventListener('mouseup', recordConsoleElementHeight); var currentConsoleElementHeight = consoleElement.offsetHeight; setContainerElementBottomMargin(currentConsoleElementHeight); } resizerElement.addEventListener('mouseup', recordConsoleElementHeight); }); }); }).call(this); </script> </body> </html>

関係すると思われるソースコード

javascript関係

app/javascript/app.vue

Vue

1 2<template> 3 <div id="app"> 4 <p>{{ message }}</p> 5 </div> 6</template> 7 8<script> 9export default { 10 data: function () { 11 return { 12 message: "Hello Vue!\nお疲れ!! ポート5000番きた", 13 } 14 } 15} 16</script> 17 18<style scoped> 19p { 20 font-size: 2em; 21 text-align: center; 22} 23</style> 24

app/javascript/packs/todo.js

javascript

1import Vue from 'vue/dist/vue.esm.js' 2import Header from './components/header.vue' 3 4var app = new Vue({ 5 router: Router, 6 el: '#app', 7 components: { 8 'navbar': Header, 9 } 10});

app/javascript/hello_vue.js

// Run this example by adding <%= javascript_pack_tag 'hello_vue' %> to the head of your layout file, // like app/views/layouts/application.html.erb. // All it does is render <div>Hello Vue</div> at the bottom of the page. import Vue from 'vue' import App from './app.vue' document.body.appendChild(document.createElement('hello')) new Vue({ el: 'hello', template: '<App/>', components: { App } })

app/javascript/pack/components/header.vue

Vue

1<template> 2 <div> 3 <ul id="dropdown" class="dropdown-content"> 4 <li><a href="#">Top</a></li> 5 <li><a href="#">About</a></li> 6 <li><a href="#">Contact</a></li> 7 </ul> 8 <nav> 9 <div class="nav-wrapper container"> 10 <a href="/" class="brand-logo left">Todo Application</a> 11 <ul class="right hide-on-med-and-down"> 12 <li><a href="#">Top</a></li> 13 <li><a href="#">About</a></li> 14 <li><a href="#">Contact</a></li> 15 </ul> 16 <ul class="right hide-on-large-only"> 17 <li> 18 <a class="dropdown-button" href="#!" data-activates="dropdown"> 19 Menu<i class="material-icons right">arrow_drop_down</i> 20 </a> 21 </li> 22 </ul> 23 </div> 24 </nav> 25 </div> 26</template>
json.jbuilder関係

app/views/api/tasks/index.json.jbuilder

json.set! :tasks do json.array! @tasks do |task| json.extract! task, :id, :name, :is_done, :created_at, :updated_at end end

app/views/api/tasks/show.json.jbuilder

json.set! :task do json.extract! @task, :id, :name, :is_done, :created_at, :updated_at end
controller関係

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base # protect_from_forgery with: :exception end

app/controllers/api/tasks_controller.rb

class Api::TasksController < ApplicationController # GET /tasks def index @tasks = Task.order('updated_at DESC') end # POST /tasks def create @task = Task.new(task_params) if @task.save render :show, status: :created else render json: @task.errors, status: :unprocessable_entity end end # PATCH/PUT /tasks/1 def update @task = Task.find(params[:id]) if @task.update(task_params) render :show, status: :ok else render json: @task.errors, status: :unprocessable_entity end end private # Never trust parameters from the scary internet, only allow the white list through. def task_params params.fetch(:task, {}).permit( :name, :is_done ) end end

補足情報(アプリケーション実行時のバージョン情報)

バージョン情報 Using rake 12.3.3 Using concurrent-ruby 1.1.5 Using i18n 1.6.0 Using minitest 5.11.3 Using thread_safe 0.3.6 Using tzinfo 1.2.5 Using activesupport 5.2.3 Using builder 3.2.3 Using erubi 1.8.0 Using mini_portile2 2.4.0 Using nokogiri 1.10.4 Using rails-dom-testing 2.0.3 Using crass 1.0.4 Using loofah 2.2.3 Using rails-html-sanitizer 1.2.0 Using actionview 5.2.3 Using rack 2.0.7 Using rack-test 1.1.0 Using actionpack 5.2.3 Using nio4r 2.5.1 Using websocket-extensions 0.1.4 Using websocket-driver 0.7.1 Using actioncable 5.2.3 Using globalid 0.4.2 Using activejob 5.2.3 Using mini_mime 1.0.2 Using mail 2.7.1 Using actionmailer 5.2.3 Using activemodel 5.2.3 Using arel 9.0.0 Using activerecord 5.2.3 Using mimemagic 0.3.3 Using marcel 0.3.3 Using activestorage 5.2.3 Using public_suffix 4.0.1 Using addressable 2.7.0 Using io-like 0.3.0 Using archive-zip 0.12.0 Using execjs 2.7.0 Using autoprefixer-rails 9.6.1.1 Using bindex 0.8.1 Using msgpack 1.3.1 Using bootsnap 1.4.5 Using bundler 2.0.2 Using byebug 11.0.1 Using regexp_parser 1.6.0 Using xpath 3.2.0 Using capybara 3.29.0 Using childprocess 2.0.0 Using chromedriver-helper 2.1.1 Using coffee-script-source 1.12.2 Using coffee-script 2.4.1 Using method_source 0.9.2 Using thor 0.20.3 Using railties 5.2.3 Using coffee-rails 4.2.2 Using dotenv 0.7.0 Using ffi 1.11.1 Using foreman 0.64.0 Using jbuilder 2.9.1 Using jquery-rails 4.3.5 Using rb-fsevent 0.10.3 Using rb-inotify 0.10.0 Using ruby_dep 1.5.0 Using listen 3.1.5 Using material_icons 2.2.1 Using materialize-sass 1.0.0 Using puma 3.12.1 Using rack-proxy 0.6.5 Using sprockets 3.7.2 Using sprockets-rails 3.2.1 Using rails 5.2.3 Using rubyzip 1.2.4 Using sass-listen 4.0.0 Using sass 3.7.4 Using tilt 2.0.9 Using sass-rails 5.1.0 Using selenium-webdriver 3.142.4 Using spring 2.1.0 Using spring-watcher-listen 2.0.1 Using sqlite3 1.4.1 Using turbolinks-source 5.2.0 Using turbolinks 5.2.0 Using uglifier 4.1.20 Using web-console 3.7.0 Using webpacker 4.0.7

原因のあてが付いておらず、長文となってしまいましたが、よろしくお願いいたします

追記:ご回答していただいた部分に対する返答

routes.rb

Rails.application.routes.draw do root to: 'home#index' get '/about', to: 'home#index' get '/contact', to: 'home#index' namespace :api, format: 'json' do resources :tasks, only: [:index, :create, :update] end end

db/schema.rb

ActiveRecord::Schema.define(version: 2019_09_08_075911) do create_table "tasks", force: :cascade do |t| t.string "name" t.boolean "is_done" t.datetime "created_at", null: false t.datetime "updated_at", null: false end end

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

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

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

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

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

guest

回答1

0

ベストアンサー

routes.rb はどうなっていますか。
POSTを受けているところがないように見えました。
それとVueは関係ないかと思います。
さらに、 JSON形式のデータがデータベースに取り込まれている とありますが、JSON型(のようなもの)を作ったわけではないですよね?

投稿2019/09/09 02:47

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

hitsujimon1984

2019/09/09 03:36 編集

10tm84さん 回答ありがとうございます。 `routes.rb`は以下のようになっています ``` Rails.application.routes.draw do root to: 'home#index' get '/about', to: 'home#index' get '/contact', to: 'home#index' namespace :api, format: 'json' do resources :tasks, only: [:index, :create, :update] end end ``` POSTは`app/controllers/api/tasks_controller.rb`のcreateアクションで受けています. 質問本文にて、tasks_controller.rbで別のコード書いてしまっていたので、以下に修正しました。 POSTを受ける場合、以下のcreateアクションだけでは、JSON形式のデータを受け取れないのでしょうか? ``` class Api::TasksController < ApplicationController # GET /tasks def index @tasks = Task.order('updated_at DESC') end # POST /tasks def create @task = Task.new(task_params) if @task.save render :show, status: :created else render json: @task.errors, status: :unprocessable_entity end end # PATCH/PUT /tasks/1 def update @task = Task.find(params[:id]) if @task.update(task_params) render :show, status: :ok else render json: @task.errors, status: :unprocessable_entity end end private # Never trust parameters from the scary internet, only allow the white list through. def task_params params.fetch(:task, {}).permit( :name, :is_done ) end end ``` .ison.jbuilderのコードで、json型のデータを作ったつもりでした。 如何せん、JSONやVue.jsについての理解がかなり浅く、的外れな返事かもしれません。
退会済みユーザー

退会済みユーザー

2019/09/09 03:41

本題への回答ではないですが、 ・今回お答えいただいたことは質問文本文に書いて、インラインコードにしてインデントなどをつけて下さい ・今回の質問内容の範囲では、Vueは関係ありません
hitsujimon1984

2019/09/09 03:44

10tm84さん ご指摘ありがとうございます! ご指摘いただいた点に関して、修正いたします。
退会済みユーザー

退会済みユーザー

2019/09/09 05:43

もう一点、お答えいただけますか。 > さらに、 JSON形式のデータがデータベースに取り込まれている とありますが、JSON型(のようなもの)を作ったわけではないですよね? 実質的には、db/schema.rb を追記して頂ければ、上記の回答になります。
hitsujimon1984

2019/09/09 06:32

10tm84さん 私が理解不足で使っていることを踏まえ、丁寧に質問してくださり、お心遣いに感謝します。 追記致しました。
退会済みユーザー

退会済みユーザー

2019/09/09 10:14

元記事にあるように、CSRF対策を無効にしていますか? 具体的には、app/controllers/application_controller.rb の中に、 protect_from_forgery という行が含まれていますか? (例) class ApplicationController < ActionController::Base protect_from_forgery end ただ、CSRF対策は安直に無効にするべきではありません。Web APIの設計に応じて適切に設定するべきです。ここらへんは調べてみて下さい。
hitsujimon1984

2019/09/18 10:36

CSRFは無効になっています 質問投稿文のapp/controllers/application_controller.rbでも コメントアウトしてあります
退会済みユーザー

退会済みユーザー

2019/09/18 20:50

> 質問投稿文のapp/controllers/application_controller.rbでもコメントアウトしてあります Rails 5.2.3ならば、コメントアウトされている行はもともと存在していないと思うのですが、これは手入力されたのでしょうか。 そしてその関連で、CSRF対策を無効にするために、上記で私が書いたようのと全く同じ書き方をしてみましたでしょうか。
hitsujimon1984

2019/09/26 12:34

10tm84さん 回答してくださっているのにも関わらず、返信が遅れ申し訳ございません。 はい、手入力しコメントアウトしました。 示していただいたコードと異なる部分は、 class ApplicationController < ActionController::Base # protect_from_forgery with: :exception end コメントアウト文中にある「with exception」でした。 よってこの部分を念の為削除し、全く同じコードで実行しましたが、同様のエラーが出ました。 質問する前に私自身、ちゃんと理解したコードを書いていないことが大きな問題だなと感じました。 なので今回は質問をここで打ち切ろうと思います。 10tm84さん、非常に丁寧にお付き合いいただきありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問