はじめに
想像以上に簡単だったので今後Reactなどでも試していきたい。
✅参考
Vue.jsとRailsでTODOアプリのチュートリアルみたいなものを作ってみた
Ruby on Rails, Vue.js で始めるモダン WEB アプリケーション入門
セットアップ
プロジェクト生成
$ rails new todo_sample --webpack=vue
コントローラ生成
$ rails g controller home index create app/controllers/home_controller.rb route get 'home/index' invoke erb create app/views/home create app/views/home/index.html.erb invoke test_unit create test/controllers/home_controller_test.rb invoke helper create app/helpers/home_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/home.coffee invoke scss create app/assets/stylesheets/home.scss
routes.rb
Rails.application.routes.draw do root to: 'home#index' get 'home/index' end
home/index.html.erb
<%= javascript_pack_tag 'hello_vue' %>
javascript_pack_tagを使用することで、app/javascript/packs以下にあるJSファイルを探してくれます。インストール時にhello_vue.jsというファイルが生成されているので、これをindexにて読み込ませます。
これでrails sして、「Hello Vue!」と表示されれば大丈夫です。
確認したところ表示されました◎

👇ファイルの確認

※いったん失敗したので割愛 起動できない。。。
gemの追加でリロードすることで自動コンパイルがされるようにします。
gem 'foreman'
インストール
$ bin/bundle※bundleコマンドなかった💦
bin/server作成
#!/bin/bash -i bundle install bundle exec foreman start -f Procfile.devProcfile.dev
web: bundle exec rails s # watcher: ./bin/webpack-watcher webpacker: ./bin/webpack-dev-serverbin/serverのパーミッション変更
$ chmod 777 bin/server
app/javascript/app.vueの編集
<template> <div id="app"> <p>Rails × Vue.js</p> <p>{{ message }}</p> </div> </template> <script> export default { data: function () { return { message: "Hello Vue.js!" } } } </script> <style scoped> p { font-size: 2em; text-align: center; } </style>
再度サーバー起動で自動コンパイル確認
$rails s

APIサーバー構築
モデル作成
$ rails generate model Task name:string is_done:boolean invoke active_record create db/migrate/20200721122943_create_tasks.rb create app/models/task.rb invoke test_unit create test/models/task_test.rb create test/fixtures/tasks.yml
マイグレファイル編集(null: false追記)
create_table :tasks do |t| t.string :name, null: false t.boolean :is_done, default: false, null: false t.timestamps
実行
$ rails db:migrate
モデル編集
class Task < ApplicationRecord validates :name, presence: true end
routes.rbの編集
Rails.application.routes.draw do root to: 'home#index' namespace :api, format: 'json' do resources :tasks, only: [:index, :create, :update] end end
コントローラ作成
$ rails g controller api/tasks index create app/controllers/api/tasks_controller.rb route namespace :api do get 'tasks/index' end invoke erb create app/views/api/tasks create app/views/api/tasks/index.html.erb invoke test_unit create test/controllers/api/tasks_controller_test.rb invoke helper create app/helpers/api/tasks_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/api/tasks.coffee invoke scss create app/assets/stylesheets/api/tasks.scss
※コントローラのコード割愛
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
db/seeds.rbの作成
3.times { Task.create!(name: 'Sample Task') } 2.times { Task.create!(name: 'Sample Task', is_done: true) }
DB適用
$ rails db:seed
※ここでAPIの取得ができなかったのでこちら参考。
app/controllers/api_controller.rb作成
class ApiController < ActionController::API end
app/controllers/api/tasks_controller.rbの編集
class Api::TasksController < ApplicationController # class Api::TasksController < ApiController # 結果どっちでも問題なさげ。 def index @tasks = Task.order('updated_at DESC') render json: @tasks end
確認
$ curl localhost:3000/api/tasks [{"id":5,"name":"Sample Task","is_done":true,"crea~~~~~,

👆とりあえずAPIサーバーの構築はできました◎
躓いた点
✅JSONの取得
以下でエラー
undefined local variable or method `json'
→json.builderではなくjson.jbuilderでした。。。💦
コントローラ編集
class Api::TasksController < ApplicationController # class Api::TasksController < ApiController # GET /tasks def index @tasks = Task.order('updated_at DESC') # render json: @tasks end
👆index.json.builderを参照するようにする。

いけました◎
参考:Railsのjbuilderの書き方と便利なイディオムやメソッド
✅POSTできない
※未解決
$ curl -X POST localhost:3000/api/tasks -d 'task[name]=fugafuga'
Reactを使う場合
Gem
gem 'react-rails' gem 'webpacker'
インストール
$ bin/bundle
$ rails webpacker:install // Vueを入れている場合conflictするのでY
$ rails webpacker:install:react
$ rails generate react:install
app/assets/javascripts/components/Hello.jsx作成
$ mkdir app/assets/javascripts/components/ $ touch app/assets/javascripts/components/Hello.jsx
編集
var HelloMessage = React.createClass({ render: function() { return ( <h1>Hello {this.props.name}!</h1> ) } });
views/index.html.erbの編集
<%# <%= javascript_pack_tag 'hello_vue' %> %> <%= react_component('HelloMessage', name: 'Mike') %>
👆表示されず。。。
Vueと同じプロジェクトで作成しちゃったからか。。。
👇以下のように、別々でアプリ生成するのが吉かもしれない。
3. Rails(API)アプリとReactアプリを別々に作成する。
最もスタンダードと言っても良い方法では無いでしょうか。
この方法では、RailsをAPIとして作成し、全く別のReactのアプリケーションを作成します。
以下の様な利点があります。
- Railsの問題はRailsで、Reactの問題はReactでと完全に別々で対処できる。
- Reactアプリケーション以外にもモバイルアプリなど、他のクライアントにも対応することができるので多様な使い方ができ、よりスケールしやすい。
この方法ではRailsとReactアプリを別々で作成し、RailsがJSON化した情報を送り、クライアント側がリクエストで受け取る構造をとりますのでそれぞれの作り方は以下を参考にしてください。
また、サンプルとして
Rails
+React
+Docker
+GraphQL
を組み合わせて設計したアプリを作成しました。
ディレクトリ構成等で参考になればと思います。
rails s 時のデフォルトのポート番号を変更する ※ポート番号変更も調べたら用意。
メモ
axiosのインストール
$ yarn add axios
application_controller.rbに以下を追加
protect_from_forgery with: :exception
コメントを残す