From 23ea32a573ead4bc1de7d47f36d8a4dbe31cea0d Mon Sep 17 00:00:00 2001 From: Lachlan Date: Tue, 13 Feb 2018 17:43:54 +0900 Subject: [PATCH 1/6] Add English version --- .DS_Store | Bin 0 -> 6148 bytes ...5\343\203\226\343\203\255\343\202\2600213" | 219 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 .DS_Store create mode 100644 "docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b1bc858e925d93fb375ed4bdb59c7154b9b72c92 GIT binary patch literal 6148 zcmeH~F>b>!3`IX%4*|M(?5HIN=naG*JwYxI#2y292)gU&`J}kS%^VoPCqO=tGGY4< zmI=TPfAbG80@%@=*n3!+F&{8v!Gzm5@b5#RJ8QCa#;1cJMgVePIgIO=CCK6hvL;(6D>TdL!Lrq2 z4DoujlO?aK$=2E1VL5zQ-r0PLp;>Q-6(%&R0R<@_1y%}t_I&j7|Cj!3{$I5yl>$=W z%@nZVcsd^VQhB!idp)n8v+CBlogs#new +

Find me in app/views/blogs/new.html.erb

+<%= content_tag :div, + id: 'blog-form-vue', + data: { + blog: @blog.to_json(), + } do %> +<% end %> +``` + +No form yet. However, this is how the Vue instance will access the @blog variable from the controller’s new action — by using Rails’ `content_tag` helper. If you look in the devtools, this HTML is generated: + +[image??] + +HTML generated using the content_tag helper + +Notice the JSON object in data-blog? + +## Creating the Vue instance + +Head over to `assets/javascripts/blogs.coffee` and add the following: + +``` +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ +# +document.addEventListener 'DOMContentLoaded', () -> + el = document.getElementById('blog-form-vue') +if el + blog = JSON.parse(el.dataset.blog) + csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content') + new Vue({ + el: el, + + data: -> + blog: blog +``` + +Pretty neat. After waiting for the DOM to render, we can access to data-blog attribute using `JSON.parse(el.dataset.blog)` after finding the element. The we simply pass the object to the our new Vue instance. We also grab the CSRF token from the meta tags. + +## Adding some validation + +Let’s add the validation. We can use Vue’s computed properties to check if the form is valid and toggle the submit button’s disabled attribute. Update `blogs.coffee`: + +``` +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ +# +document.addEventListener 'DOMContentLoaded', () -> + el = document.getElementById('blog-form-vue') + blog = JSON.parse(el.dataset.blog) + csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content') + if el + new Vue({ + el: el, + + data: -> + blog: blog + titleError: 'Title has to be at least 5 characters' + bodyError: 'Body has to be at least 10 characters' + csrfToken: csrfToken + computed: + valid: ()-> + @blog.title.length > 5 && @blog.body.length > 10 + }) +``` + +And the form (views/blogs/new.html.erb): + +``` +

Blogs#new

+

Find me in app/views/blogs/new.html.erb

+<%= content_tag :div, + id: 'blog-form-vue', + data: { + blog: @blog.to_json() + } do %> +
+ + +
+ The title needs to be at least 5 characters. +
+ + +
+ The body needs to be at least 10 characters. +
+ +
+<% end %> + +``` + +Notable points: +- We can bind to the forms disabled attribute and automatically disable the button if the form is not valid using :disabled="!valid" . +- We use v-model to achieve two-way binding on the blog’s title and body. +- We submit the form using form @submit.prevent=”submit” . prevent ensures the page does not redirect — we will leave that up to the submit method we are about to write. +- We use v-if to conditionally show form errors. + +## Submitting the form + +Let’s add the submit method to the Vue instance: + +``` +methods: + buildRequest: ()-> + headers = new Headers() + headers.append('Content-Type', 'application/json') + headers.append('X-Requested-With', 'XMLHttpRequest') + headers.append('X-CSRF-TOKEN', @csrfToken) + new Request('/blogs', { + headers: headers, + method: 'POST', + credentials: 'same-origin', + body: JSON.stringify({ title: @blog.title, body: @blog.body }) + }) + submit: ()-> + window.fetch @buildRequest() + .then (data) -> + if data.status == 201 + window.location.href = '/blogs' +``` + +We use the fetch web API to submit the form asynchronously. We have to add the Content-Type as json, so the Rails controller knows how to process the form, and some other headers. We should also call JSON.stringify on the body of the request, or Object [object] will be sent instead. Lastly, we redirect using `window.location.href` to the index and show all the blogs. + From abf0bb496182f61ea77d3fbd81ecce52cc1a44cf Mon Sep 17 00:00:00 2001 From: Lachlan Date: Tue, 13 Feb 2018 17:45:40 +0900 Subject: [PATCH 2/6] Add repo --- ...231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" | 2 ++ 1 file changed, 2 insertions(+) diff --git "a/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" "b/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" index 4d36c95..3afe1f1 100644 --- "a/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" +++ "b/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" @@ -1,6 +1,8 @@ こんにちは。フルスタックエンジニアのミラーです。 +Repo: https://github.com/lmiller1990/vue-rails-form-validation + Vue.js can be used for building scalable, complex single page applications, which is generally what I blog about. However, another value use case is as a utility library to add some dynamic functionality to server rendered applications.  This article will look at how we can use Vue.js to add some client side form validation in a Rails application. From e28b292254ae7a3a09c3778016082fb5ab84599a Mon Sep 17 00:00:00 2001 From: Lachlan Date: Mon, 26 Feb 2018 18:08:17 +0900 Subject: [PATCH 3/6] Add bad japanese translation --- ...5\343\203\226\343\203\255\343\202\2600213" | 183 +++++++++--------- 1 file changed, 96 insertions(+), 87 deletions(-) diff --git "a/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" "b/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" index 3afe1f1..3a3b87e 100644 --- "a/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" +++ "b/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" @@ -1,80 +1,73 @@ -こんにちは。フルスタックエンジニアのミラーです。 +こんにちは。フルスタックエンジニアのミラーです。ぶらニューで、RailsとVue.jsで[EAT](start.eat.auto)の開発をしています。 +Vue.jsで複雑でスケーラベルなSPAを作るのに使えますが、伝統的なサーバーでレンダーされるアプリケーションに動的な行動をつけるためにも便利です。 -Repo: https://github.com/lmiller1990/vue-rails-form-validation +この記事でRailsアプリケーションにVue.jsでフォームバリデーションをします。 -Vue.js can be used for building scalable, complex single page applications, which is generally what I blog about. However, another value use case is as a utility library to add some dynamic functionality to server rendered applications.  -This article will look at how we can use Vue.js to add some client side form validation in a Rails application. +ソースコードはこちらで。https://github.com/lmiller1990/vue-rails-form-validation -## Setup +`rails new blogger`で新しいレイルズアピリケーションをさくせいします。Vue.jsを`webpacker`で追加するのも可能ですが、この記事でデフォルトのアセットパイプラインで追加します。 -Scaffold a new application using rails new blogger. A future article will look at how to use the new webpacker gem to bundle the application using webpack; for simplicity, I’ll stick with the usual Rails asset pipeline for now. -After creating the Rails app, add the following to your Gemfile: +`Gemfile`で`vuejs-rails`を追加します。 -gem 'vuejs-rails' +`gem 'vuejs-rails` -and bundle install. This adds Vue to the asset pipeline. Lastly, we need to include it in assets/javascripts/application.js: +そして`bundle install`。これでVue.jsをアセットパイプラインに追加します。最後に`assets/javascripts/application.js`で: -//= require vue  +`//= require vue` -## Creating the controller and model +### コントローラとモデルを作成 +ow作成アピリケーションは簡単です。ただのフォームで`blog`を作ります。`blog`には`title`, `body`があります。コントローラを作ります。 -This will be a simple form — it allows the user to create a Blog, which has a title and body, with minimum lengths of 5 and 10. Firstly, create the controller and actions: +`rails generate controller blogs index create new` -``` -rails generate controlls blogs index create new -``` +とモデル: -and the model: +`rails generate model blog title:string body:string` -``` -rails generate model blog title:string body:string -``` +と、データベースをマイグレートします: -migrate your database with `bin/rails db:migrate`. +`bin/rails db:migrate` -## Adding the routes +### ロートを追加 +`config/routes.rb`を更新します: -Creating the routes is easy. Update `routes.rb`: ``` Rails.application.routes.draw do resources :blogs end ``` -## Creating the controller actions - -For the purpose of this demo, we only need three actions: `create`, `new` and `index`. We will also whitelist the params as is usual in Rails controllers. +### コントローラのアクションを作成 -```rb +``` class BlogsController < ApplicationController -def index + def index @blogs = Blog.all -end - -def create - @blog = Blog.new(blog_params) - if @blog.save! - render json: {}, status: :created - else - render json: {}, status: :internal_server_error - end -end - -def new + end + def create + @blog = Blog.new(blog_params) + if @blog.save! + render json: {}, status: :created + else + return :internal_server_error + end + end + def new @blog = Blog.new(title: 'Title', body: '') -end - -private + end -def blog_params + private + def blog_params params.require(:blog).permit(:title, :body) end end +``` -## Creating the view +一般的なレイルズのコントローラです。これからVueを使います! -This is where things get a bit interesting. We need to pass the data from @blog to the Vue instance (which we have not made yet). Update app/views/blogs/new.html.erb, which should have been generated when you scaffolded the controller earlier: +### ビューを作成 +コントローラの`new`アクションで定義された`@blog`をビューのフォームに渡さないといけません。`app/views/blogs/new.html.erb`を更新します: ```

Blogs#new

@@ -87,52 +80,47 @@ This is where things get a bit interesting. We need to pass the data from @blog <% end %> ``` -No form yet. However, this is how the Vue instance will access the @blog variable from the controller’s new action — by using Rails’ `content_tag` helper. If you look in the devtools, this HTML is generated: - -[image??] +`content_tag`で`data`に`@blog`を`to_json`で渡します。マークアップを見ると、こうなります: -HTML generated using the content_tag helper - -Notice the JSON object in data-blog? +``` +
-## Creating the Vue instance +https://cdn-images-1.medium.com/max/800/1*mzcXtB19FJ386_JgNHMCGQ.png -Head over to `assets/javascripts/blogs.coffee` and add the following: +### Vueインスタナスを作成 +`assets/javascripts/blogs.coffee`を更新します: ``` -# Place all the behaviors and hooks related to the matching controller here. -# All this logic will automatically be available in application.js. -# You can use CoffeeScript in this file: http://coffeescript.org/ -# document.addEventListener 'DOMContentLoaded', () -> el = document.getElementById('blog-form-vue') -if el blog = JSON.parse(el.dataset.blog) csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content') - new Vue({ - el: el, - - data: -> - blog: blog + + if el + new Vue({ + el: el, + + data: -> + blog: blog ``` -Pretty neat. After waiting for the DOM to render, we can access to data-blog attribute using `JSON.parse(el.dataset.blog)` after finding the element. The we simply pass the object to the our new Vue instance. We also grab the CSRF token from the meta tags. - -## Adding some validation +DOMのレンダーが完了すると、`new.html.erb`で作った`
el = document.getElementById('blog-form-vue') - blog = JSON.parse(el.dataset.blog) - csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content') + if el - new Vue({ + blog = JSON.parse(el.dataset.blog) + csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content') + + new Vue({ el: el, data: -> @@ -146,7 +134,7 @@ document.addEventListener 'DOMContentLoaded', () -> }) ``` -And the form (views/blogs/new.html.erb): +そして、フォームも更新します:(`views/blogs/new.html.erb`)。 ```

Blogs#new

@@ -156,7 +144,7 @@ And the form (views/blogs/new.html.erb): data: { blog: @blog.to_json() } do %> -
+
@@ -187,15 +175,16 @@ input[type="submit"] { ``` -Notable points: -- We can bind to the forms disabled attribute and automatically disable the button if the form is not valid using :disabled="!valid" . -- We use v-model to achieve two-way binding on the blog’s title and body. -- We submit the form using form @submit.prevent=”submit” . prevent ensures the page does not redirect — we will leave that up to the submit method we are about to write. -- We use v-if to conditionally show form errors. +面白い点: +- `disabled`属性にバイドして、フォームを検証して問題があれば自動的に`disabled=true`:`:disabled="!valid"`。 +- `v-model`でブログの`title`, `body`でバインとします。 +- `@submit.prevent="submit"`でフォームを送信します。これから`submit`を書きます。ページを同期に送信します。 +- `v-if` -## Submitting the form +https://cdn-images-1.medium.com/max/800/1*ewA3RABqTEE8FFTxePERiQ.png -Let’s add the submit method to the Vue instance: +### フォームを送信します +`blogs.coffee`で`submit`メソッドを追加します。 ``` methods: @@ -212,10 +201,30 @@ methods: }) submit: ()-> window.fetch @buildRequest() - .then (data) -> - if data.status == 201 - window.location.href = '/blogs' + .then (data) -> + if data.status == 201 + window.location.href = '/blogs' ``` -We use the fetch web API to submit the form asynchronously. We have to add the Content-Type as json, so the Rails controller knows how to process the form, and some other headers. We should also call JSON.stringify on the body of the request, or Object [object] will be sent instead. Lastly, we redirect using `window.location.href` to the index and show all the blogs. +`fetch`でフォームを同期的に送信します。ひつようなヘッダーを追加しないと送信できません。`body`を`JSON.stringify`しないと`Object [object]`のままで送信されてしまします。 + +問題がなければ、201レスポンスがコントローラから戻って、`index`に飛ばします。 + +`views/blogs/index.html.erb`で全てのブログを表示します: + +``` +

Blogs#index

+

Find me in app/views/blogs/index.html.erb

+
    + <% @blogs.each do |blog| %> +
  • Title: <%= blog.title %> body: <%= blog.body %>
  • + <% end %> +
+``` + +https://cdn-images-1.medium.com/max/800/1*q1k6OnSzkwV7r2gLoozj5w.png + +### おもため +Vue.jsをSPAによく使いますが、伝統的なサーバーアプリにも使うことも便利です。今後の記事でVue.jsをwebpackでバンドルしてアプリケーションを作成してみます。 +ソースコードはこちらで。https://github.com/lmiller1990/vue-rails-form-validation \ No newline at end of file From 9b9e6d4e0d14318202cb414fb5b1dc28c39c9c88 Mon Sep 17 00:00:00 2001 From: Lachlan Date: Mon, 26 Feb 2018 18:13:28 +0900 Subject: [PATCH 4/6] Ignore .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index b1bc858e925d93fb375ed4bdb59c7154b9b72c92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~F>b>!3`IX%4*|M(?5HIN=naG*JwYxI#2y292)gU&`J}kS%^VoPCqO=tGGY4< zmI=TPfAbG80@%@=*n3!+F&{8v!Gzm5@b5#RJ8QCa#;1cJMgVePIgIO=CCK6hvL;(6D>TdL!Lrq2 z4DoujlO?aK$=2E1VL5zQ-r0PLp;>Q-6(%&R0R<@_1y%}t_I&j7|Cj!3{$I5yl>$=W z%@nZVcsd^VQhB!idp)n8v+C Date: Sat, 10 Mar 2018 14:35:19 +0900 Subject: [PATCH 5/6] Fix grammatically errors --- ...5\343\203\226\343\203\255\343\202\2600213" | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git "a/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" "b/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" index 819ffc7..61c500f 100644 --- "a/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" +++ "b/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" @@ -1,12 +1,12 @@ -こんにちは。フルスタックエンジニアのミラーです。ぶらニューで、RailsとVue.jsで[EAT](start.eat.auto)の開発をしています。 +こんにちは。フルスタックエンジニアのミラーです。ブラニューで、RailsとVue.jsで[EAT](start.eat.auto)の開発をしています。 -Vue.jsで複雑でスケーラベルなSPAを作るのに使えますが、伝統的なサーバーでレンダーされるアプリケーションに動的な行動をつけるためにも便利です。 +Vue.jsで複雑でスケーラブルなSPAを作るのに使えますが、従来的なサーバーレンダーされるアプリケーションに動的アクションを付けるのにも便利です。 この記事でRailsアプリケーションにVue.jsでフォームバリデーションをします。 ソースコードはこちらで。https://github.com/lmiller1990/vue-rails-form-validation -`rails new blogger`で新しいレイルズアピリケーションをさくせいします。Vue.jsを`webpacker`で追加するのも可能ですが、この記事でデフォルトのアセットパイプラインで追加します。 +`rails new blogger`で新しいRailsアプリケーションを作成します。Vue.jsを`webpacker`で追加するのも可能ですが、この記事でデフォルトのアセットパイプラインで追加します。 `Gemfile`で`vuejs-rails`を追加します。 @@ -17,7 +17,7 @@ Vue.jsで複雑でスケーラベルなSPAを作るのに使えますが、伝 `//= require vue` ### コントローラとモデルを作成 -ow作成アピリケーションは簡単です。ただのフォームで`blog`を作ります。`blog`には`title`, `body`があります。コントローラを作ります。 +アプリケーション作成は簡単です。ただのフォームで`blog`を作ります。`blog`には`title`, `body`があります。コントローラを作ります。 `rails generate controller blogs index create new` @@ -25,7 +25,7 @@ ow作成アピリケーションは簡単です。ただのフォームで`blog` `rails generate model blog title:string body:string` -と、データベースをマイグレートします: +と、モデルとデータベースをマイグレートします: `bin/rails db:migrate` @@ -64,10 +64,10 @@ class BlogsController < ApplicationController end ``` -一般的なレイルズのコントローラです。これからVueを使います! +一般的なRailsのコントローラです。これからVueを使います! -### ビューを作成 -コントローラの`new`アクションで定義された`@blog`をビューのフォームに渡さないといけません。`app/views/blogs/new.html.erb`を更新します: +### Viewを作成を作成 +コントローラの`new`アクションで定義された`@blog`をViewを作成のフォームに渡さないといけません。`app/views/blogs/new.html.erb`を更新します: ```

Blogs#new

@@ -90,7 +90,7 @@ end https://cdn-images-1.medium.com/max/800/1*mzcXtB19FJ386_JgNHMCGQ.png -### Vueインスタナスを作成 +### Vueインスタンスを作成 `assets/javascripts/blogs.coffee`を更新します: ``` @@ -167,8 +167,8 @@ input[type="submit"] { ``` 面白い点: -- `disabled`属性にバイドして、フォームを検証して問題があれば自動的に`disabled=true`:`:disabled="!valid"`。 -- `v-model`でブログの`title`, `body`でバインとします。 +- `disabled`属性にバインドして、フォームを検証して問題があれば自動的に`disabled=true`:`:disabled="!valid"`。 +- `v-model`でブログの`title`, `body`でバインドします。 - `@submit.prevent="submit"`でフォームを送信します。これから`submit`を書きます。ページを同期に送信します。 - `v-if` @@ -197,7 +197,7 @@ methods: window.location.href = '/blogs' ``` -`fetch`でフォームを同期的に送信します。ひつようなヘッダーを追加しないと送信できません。`body`を`JSON.stringify`しないと`Object [object]`のままで送信されてしまします。 +`fetch`でフォームを同期的に送信します。必要なヘッダーを追加しないと送信できません。`body`を`JSON.stringify`しないと`Object [object]`のままで送信されてしまします。 問題がなければ、201レスポンスがコントローラから戻って、`index`に飛ばします。 @@ -215,7 +215,7 @@ methods: https://cdn-images-1.medium.com/max/800/1*q1k6OnSzkwV7r2gLoozj5w.png -### おもため +### まとめ Vue.jsをSPAによく使いますが、伝統的なサーバーアプリにも使うことも便利です。今後の記事でVue.jsをwebpackでバンドルしてアプリケーションを作成してみます。 ソースコードはこちらで。https://github.com/lmiller1990/vue-rails-form-validation From c5caa02129ab53ecc2d93cdd308cb875f4b6697a Mon Sep 17 00:00:00 2001 From: Lachlan Date: Tue, 13 Mar 2018 15:05:43 +0900 Subject: [PATCH 6/6] =?UTF-8?q?Update=20=E9=96=8B=E7=99=BA=E8=80=85?= =?UTF-8?q?=E3=83=96=E3=83=AD=E3=82=B00213?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" "b/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" index 61c500f..024a196 100644 --- "a/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" +++ "b/docs/\351\226\213\347\231\272\350\200\205\343\203\226\343\203\255\343\202\2600213" @@ -1,6 +1,6 @@ こんにちは。フルスタックエンジニアのミラーです。ブラニューで、RailsとVue.jsで[EAT](start.eat.auto)の開発をしています。 -Vue.jsで複雑でスケーラブルなSPAを作るのに使えますが、従来的なサーバーレンダーされるアプリケーションに動的アクションを付けるのにも便利です。 +Vue.jsでは複雑でスケーラブルなSPAを作るのに使えますが、従来的なサーバーレンダーされるアプリケーションに動的アクションを付けるのにも便利です。 この記事でRailsアプリケーションにVue.jsでフォームバリデーションをします。