rails+vueの開発環境でフォームのpost通信を行う方法
今回もvue
+rails
のプロジェクトにおいて自分が実際にハマった?体験を記事にしていきます。
開発環境
やりたいこと
railsで新規投稿ページや編集ページを作成する場合、よく利用される方法として標準で用意されれいるform_forやform_tagなどがあります。
タイトルにもあるように今回実現したいこととしては、.vue
の単一ファイルコンポーネントを使用してformの送信をしたいです。
.erb
ファイルの中ではform_tagを使用できますが、.vue
ファイルでは使用することができません。
rails4から標準でCSRFへの対応をしてくれています。
そのためform_tagなどのヘルパーメソッドが実行された時に下記のようにauthenticity_token
が埋め込まれます。
<input name="authenticity_token" type="hidden" value="4aEXK2Ztfe+8fUEz5QrRYw6oETI1OWL0Lkg+EQyz81TixmxF1x7niphP2ROHngj0AY2iu3lZwTfbd4y2Tf93oA==">
今回はrailsが用意てくれているformのヘルパーメソッドは使用しないのでvue側で用意してあげなければいけません。
vueとrailsの連携についての記事はこちらを参考にしてみてください。
解決方法
railsではトークンを作成してくれるform_authenticity_tokenというメソッドがあるみたいです。それを今回は利用します。
新規作成ページを例にします。
rails側のファイル
<div class="postNew"> <new-component :post="post" :token="authenticationToken"></new-component> </div> <script> new PostNew({ el: '.postNew', data:{ post: <%= raw @post.to_json %>, authenticationToken: '<%= form_authenticity_token %>' } }) </script>
上のコードではvueモデルのdataに投稿データとトークンを渡しています。
vuemodelを定義しているファイル
下記はvue-class-componentを使用しています。
import { Vue, Component } from 'vue-property-decorator'; import New from "../../component/post/new.vue"; @Component({ components: { "new-component": New } }) export default class PostNew extends Vue { } (<any>window).PostNew = PostNew;
新規登録ページ用の単一ファイルコンポーネントを登録し、windowのプロパティにクラスを追加しています。
vueファイル
<template> <div class='wrapper'> <form action='/posts' method="post"> <input name="authenticity_token" type="hidden" :value="token"> <!--省略--> </form> </div> </template> <script lang="ts"> import { Component, Vue, Prop } from "vue-property-decorator"; import Post from "../data/post"; export default class New extends Vue { @Prop() public post: Post; @Prop() public token: string; } </script> <style> </style>
ここで大切なのはpropで受け取った値をinput
タグのvalueにいれている箇所です。
こうすることでformにトークンを埋め込むことができました。
ブラウザで表示した結果です。
この処理を記述する前は、postした時にInvalidAuthenticityToken
と下記のエラーが表示されていました。
ですが、上記の処理をすることで埋め込まれたトークンが正しく認証されました!!
まとめ
rails側からvue側へどのようなものを渡してあげるべきかを上手にやってあげればなんとかうまくできるといった感じです。(ざっくりですみません) 今後もvueとrailsで詰まったことやこれは便利だと思ったことを記事にいていきます。