LoginSignup
8
8

More than 3 years have passed since last update.

Rails6 Vueの連動方法(環境構築から)

Last updated at Posted at 2020-09-23

はじめに

Dockerを用いてRails,Vue,Posgre環境下で開発したいなと思った時に、
Rails,Vueの環境作りに手こずりましたので自分のメモとして保存します。

この記事で分かること

・Rails6とVueとPostgresのDocker環境が構築できる
・RailsとVueの連動ができる
・PryにてインスタンスとDBの操作ができる

環境

MacOS Mojave
Ruby 2.6.4
Rails 6.0.3.3
Vue 2.6.12
Webpack 4.44.2
yarn 1.22.5
Docker 2.3.0.5
VScode

Githubのリンク

僕のGithubのDocker-Start-Kitです。よろしければご活用ください。
Whiro0501/Docker_Rails6_Vue

Docker環境をMacに構築

ターミナルを開く
mkdirで任意の名前のディレクトリを作成
cdで作成したディレクトリに移動
code.でVScodeを開く

terminal
mkdir qiita
cd qiita
code .

VScodeが起動
VScode上のターミナルで作業していくので
ターミナルが起動していなければ⬆︎+Control+@でターミナルを開く

VScodeのターミナル上で以下コマンドを入力してリモートリポジトリのファイルをローカルにコピー

VScode
git clone https://github.com/Whiro0501/Docker_Rails6_Vue.git

cdでDocker_Rails6_Vue/ディレクトリに移動

VScode
cd Docker_Rails6_Vue/

以下コマンドを実行してDockerイメージをビルド

VScode
docker-compose build

以下を実行して、必要なノードモジュールを取得

VScode
docker-compose run web yarn install --check-files

以下を実行して DB(Postgres)を作成

VScode
docker-compose run web rake db:create

別のターミナルを開く
以下を実行してレールズアプリケーションを起動

VScode
#別ターミナルが億劫なら、docker-compose up -dでも良い 
docker-compose up

さらに別のターミナルを開く
Viewを更新するたび毎回コンパイルが発生し、時間がかかるため以下を実行

VScode
docker-compose exec web ./bin/webpack-dev-server

Webブラウザで以下にアクセス

Webブラウザ
http://localhost:3000

Railsアプリケーションが起動することを確認

スクリーンショット 2020-09-23 20.42.47.png

VueとRailsの連動ってどうやるの?

初期構築時点ではRailsとVueが連動されておりませんので連動させていく。

以下でhomeコントローラを作成する(コントローラー名はなんでも良い)。

VScode
docker-compose exec web rails g controller home index

index.html.erbが作成

index.html.erb
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>

以下ファイルに"root to: 'home#index'"を追加

routes.rb

Rails.application.routes.draw do
  root to:  'home#index'
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

Webブラウザで以下にアクセス

Webブラウザ
http://localhost:3000

まずはindex.html.erbに記述されている内容が表示

スクリーンショット 2020-09-23 21.07.31.png

Rails側で下地ができたので、次にVueとの連動の設定
app.vueの初期設定

app.vue
<template>
  <div id="app">
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data: function () {
    return {
      message: "Hello Vue!"
    }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>

hello_vue.jsの初期設定

hello_vue.js
import Vue from 'vue'
import App from '../app.vue'

document.addEventListener('DOMContentLoaded', () => {
  const app = new Vue({
    render: h => h(App)
  }).$mount()
  document.body.appendChild(app.$el)

  console.log(app)
})

app.vueが単一ファイルコンポーネントであり、
hello_vue.jsにオブジェクトとして渡される。
それをindex.html.erbに表示させるよう設定する。

index.html.erbを以下の通り設定

index.html.erb
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>

<%= javascript_pack_tag 'hello_vue.js' %>
<%= stylesheet_pack_tag 'hello_vue.js' %>

Webブラウザで以下にアクセス

Webブラウザ
http://localhost:3000

Vueとの連動が完了!!

スクリーンショット 2020-09-23 21.23.06.png

Githubののファイルの説明

Whiro0501/Docker_Rails6_Vue
まず上記リンクのGithubの状態から説明する
端的に説明すると以下2つを設定した後の状態となる
従ってRails6とVueとPostgresが使用できる環境を整えることができるという理屈である。

VScode
docker-compose run web rails new . --force --database=postgresql --webpack=vue

加えて上記の状態だとPostgresがうまくRailsと連動できないため以下のように設定する。
こちらも公式ドキュメントを参考とした。

database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test


production:
  <<: *default
  database: myapp_production
  username: myapp
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>

Dockerfile

公式ドキュメントのベストプラクティスを参照にした。
DockerはFROM, RUN, COPY毎にレイヤーが作成されるため
RUNやCOPYはできるだけまとめると少ないレイヤーで収めることができるとのこと。

Dockerfile
FROM ruby:2.6

# `apt-get install yarn`とするとエラーになる
# プロジェクトに必要なツールをインストール
# &&で繋げてコマンドを実行することによりレイヤーを1つとする
#apt-get update と apt-get installは同一RUN上で行う(分けると最新版を使用できない)
#RUNはイメージの作成次に実行(CMDはコンテナ起動時に実行)
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
    apt-get update -qq && apt-get install -y nodejs postgresql-client vim && \
    apt-get install -y yarn

# ディレクトリの作成
RUN mkdir /myapp

# 作業ディレクトリの指定
#RUN ,  COPY,  ADD 命令のみレイヤを作成するためWORKDIRは気にしなくて良い
# 絶対パスとする
WORKDIR /myapp

# Gemfileが更新された時のみ、レイヤを再構築
#先にプロジェクト全体をコピーしないのはレイヤーを分けるため
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
# ライブラリの依存関係をインストール
RUN bundle install

# プロジェクト全体をコピー(Gemfile/Gemfile.lockはコピーされない)
COPY . /myapp

#コンテナを起動する毎に実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

#コンテナの公開ポート番号の指定
EXPOSE 3000

#指定しなければコンテナ起動時にデフォルトで実行する処理
#Dockerfile では CMD 命令を 1 つしか記述できない
#ENTRYPOINT 命令に対するデフォルト引数としてCMDを使用可能
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose

docker-compose.ymlもDocker公式ドキュメントを参考にした。

docker-compose.yml
version: '3'
services:
    db:
        # DBにpostgresを使用
        image: postgres
        # ホストの./tmp/dbと/var/lib/postgresql/dataを同期させる
        volumes:
            - ./tmp/db:/var/lib/postgresql/data
        # 環境変数の指定
        environment:
            POSTGRES_PASSWORD: password
    web:
        build: .
        # コンテナ起動時にserver.pidを削除し、rails sを実行する
        command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
        # ホストのカレントディレクトリをコンテナの/myappと同期させる
        volumes:
            - .:/myapp
        # ホストとコンテナ間をポートフォワードする
        ports:
            - '3000:3000'
        # サービス間の依存関係
        depends_on:
            - db
        # Docker環境でByebugを使用
        stdin_open: true
        tty: true

Gemfile

Gemfileに関してはデフォルトで入っているもの主となる。
追加したパッケージはコメントしているため不要であれば削除して構わない

Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }


ruby '2.6.6'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.3'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  #デバックツールの導入
  gem 'pry-rails'
  gem 'pry-byebug'
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '~> 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  #自動補完用ツールの導入
  gem 'solargraph'
  #静的コード解析ツールの導入
  gem 'rubocop'
  gem 'rubocop-rails'
  #erbのフォーマットツールの導入
  gem 'htmlbeautifier'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

package.json

package.jsonについてはvue-routerとvuexを使いたいため追加している
Vuetify等、UIフレームワークを使用したいようであれば追加する。

package.json
{
    "name": "myapp",
    "private": true,
    "dependencies": {
        "@rails/actioncable": "^6.0.0",
        "@rails/activestorage": "^6.0.0",
        "@rails/ujs": "^6.0.0",
        "@rails/webpacker": "4.3.0",
        "turbolinks": "^5.2.0",
        "vue": "^2.6.12",
        "vue-loader": "^15.9.3",
        "vue-template-compiler": "^2.6.12",
        "vue-router": "^3.0.1",
        "vuex": "^3.0.1"
    },
    "version": "0.1.0",
    "devDependencies": {
        "webpack-dev-server": "^3.11.0"
    }
}

Railsでデバッグする

VScode上のターミナルを開く
以下をターミナルで実行

VScode
docker-compose exec web rails console

pry が起動

VScode
[1] pry(main)> 

postコントローラーを作成

docker-compose exec web rails g controller post index

post_controller.rbを修正

post_controller.rb
class PostController < ApplicationController
  def index
    @post = Post.all
  end
end

postのモデルを作成

VScode
docker-compose exec web rails g model post name:string age:integer

DBにモデルを反映させる

VScode
docker-compose exec web rails db:migrate

index.html.erbを以下に書き換え

index.html.erb
<%= @post.name %>
<%= @post.age %>

routes.rbを以下に修正

routes.rb
Rails.application.routes.draw do
  root to:  'post#index'
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

pryでPostモデルのインスタンスを作成

VScode
@post = Post.new
=> #<Post:0x00005589bc4beb78 id: nil, name: nil, age: nil, created_at: nil, updated_at: nil>

#まだnameやageにはデータを入れていない
#DBに保存もされていない
Post.all
=>   Post Load (2.2ms)  SELECT "posts".* FROM "posts"
[]

#DBにインスタンスを保存する
@post.save
   (0.7ms)  BEGIN
  Post Create (5.9ms)  INSERT INTO "posts" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"  [["created_at", "2020-09-23 13:06:47.962085"], ["updated_at", "2020-09-23 13:06:47.962085"]]
   (3.1ms)  COMMIT
=> true

#もう一度Post.allをしてデータをDBから取得すると保存したインスタンスが呼び出される
Post.all
=>   Post Load (2.2ms)  SELECT "posts".* FROM "posts"
[#<Post:0x00005589bceec5f0
  id: 1,
  name: nil,
  age: nil,
  created_at: Wed, 23 Sep 2020 13:06:47 UTC +00:00,
  updated_at: Wed, 23 Sep 2020 13:06:47 UTC +00:00>]

#@postインスタンスにデータを入れてみる
@post.name = "Hiro"
=> "Hiro"

@post.age = "29"
=> "29"

#再び保存
@post.save
Post Update (4.0ms)  UPDATE "posts" SET "name" = $1, "updated_at" = $2 WHERE "posts"."id" = $3  [["name", "Hiro"], ["updated_at", "2020-09-23 13:10:26.486888"], ["id", 1]]
Post Update (2.0ms)  UPDATE "posts" SET "age" = $1, "updated_at" = $2 WHERE "posts"."id" = $3  [["age", 29], ["updated_at", "2020-09-23 13:10:56.785029"], ["id", 1]]
   (1.0ms)  COMMIT
=> true

#データが保存されている
Post.all
=>   Post Load (1.4ms)  SELECT "posts".* FROM "posts"
[#<Post:0x00007f1ddc7a77a8
  id: 1,
  name: "Hiro",
  age: 29,
  created_at: Wed, 23 Sep 2020 13:06:47 UTC +00:00,
  updated_at: Wed, 23 Sep 2020 13:10:56 UTC +00:00>]

Webブラウザで以下にアクセス

Webブラウザ
http://localhost:3000

以下のようにDBからデータを取得できればOK

スクリーンショット 2020-09-23 22.27.01.png

Binding.pryを試してみる

post_controller.rbを修正

class PostController < ApplicationController
  def index
    binding.pry
    @post = Post.all
  end
end

Webブラウザで以下にアクセス

Webブラウザ
http://localhost:3000

以下の画面でフリーズする(正しい挙動)
スクリーンショット 2020-09-23 22.30.19.png

pryのターミナルに戻る

pry(main)> 

以上で、pryでデバッグする環境が整った

参考

以下のサイトを参考にさせていただきました。
Docker ドキュメント日本語化プロジェクト
クィックスタート: Compose と Rails
Dockerfile のベストプラクティス
Webpacker の基本的な仕組み
Dockerを使って「Rails / PostgreSQL」の開発環境を作ろう!

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8