How to link Rails6 Vue (from environment construction)

Introduction

When you want to develop under Rails, Vue, Posgre environment using Docker, I had a hard time creating the environment for Rails and Vue, so save it as my own memo.

What you can see in this article

・ Rails 6 and Vue and Postgres Docker environment can be built ・ Rails and Vue can be linked ・ You can operate the instance and DB with Pry.

environment

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 link

This is Docker-Start-Kit from my Github. Please use it if you like. Whiro0501/Docker_Rails6_Vue

Build a Docker environment on your Mac

Open terminal Create a directory with any name with mkdir Change to the directory created by cd Open VScode with code.

terminal


mkdir qiita
cd qiita
code .

VS code starts I'm working in a terminal on VScode If the terminal is not running, open the terminal with ⬆︎ + Control + @

Copy the files in the remote repository locally by entering the following command on the VScode terminal

VScode


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

cd to Docker_Rails6_Vue / directory

VScode


cd Docker_Rails6_Vue/

Build the Docker image by executing the following command

VScode


docker-compose build

Get the required node module by doing the following

VScode


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

Create DB (Postgres) by executing the following

VScode


docker-compose run web rake db:create

Open another terminal Launch the Rails application by doing the following

VScode


#If another terminal is awkward, docker-compose up -d is fine
docker-compose up

Open yet another terminal Every time I update the View, it compiles and it takes time, so do the following:

VScode


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

Access the following with a web browser

Web browser

http://localhost:3000

Make sure the Rails application starts

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

How do you work with Vue and Rails?

Rails and Vue are not linked at the time of initial construction, so we will link them.

Create a home controller below (the controller name can be anything).

VScode


docker-compose exec web rails g controller home index

Created by index.html.erb

rb:index.html.erb


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

Add "root to:'home # index'" to the following files

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

Access the following with a web browser

Web browser

http://localhost:3000

First of all, the contents described in index.html.erb are displayed

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

Now that the groundwork has been created on the Rails side, the next setting is to link with Vue. Initial settings for 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>

Initial setting of 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 is a single file component Passed as an object to hello_vue.js. Set it to be displayed in index.html.erb.

Set index.html.erb as follows

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' %>

Access the following with a web browser

Web browser

http://localhost:3000

Linkage with Vue is complete !!

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

File description on Github

Whiro0501/Docker_Rails6_Vue First, I will explain from the state of Github of the above link To briefly explain, it will be the state after setting the following two Therefore, it is the theory that it is possible to prepare the environment where Rails 6, Vue and Postgres can be used.

VScode


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

In addition, in the above state, Postgres cannot work well with Rails, so set as follows. This is also based on the official document.

database.yml: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

I referred to the best practices in the official documentation. Because Docker creates layers for each FROM, RUN, COPY It is said that RUN and COPY can be stored in as few layers as possible.

Dockerfile


FROM ruby:2.6

# `apt-get install yarn`Will result in an error
#Install the tools needed for your project
# &&Make one layer by connecting with and executing the command
#apt-get update and apt-get install is done on the same RUN(If you divide it, you cannot use the latest version)
#RUN creates image and then runs(CMD runs when container starts)
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

#Creating a directory
RUN mkdir /myapp

#Specifying the working directory
#RUN ,  COPY,You don't have to worry about WORKDIR because only ADD instructions create layers.
#Absolute pass
WORKDIR /myapp

#Rebuild layers only when Gemfile is updated
#The reason why I don't copy the whole project first is to separate the layers
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
#Install library dependencies
RUN bundle install

#Copy the entire project(Gemfile/Gemfile.lock is not copied)
COPY . /myapp

#Added a script that is executed every time the container is started
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

#Specifying the public port number of the container
EXPOSE 3000

#If not specified, the process to be executed by default when the container is started
#Only one CMD instruction can be written in a Dockerfile
#CMD can be used as the default argument for the ENTRYPOINT instruction
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose docker-compose.yml also referred to the official Docker documentation.

docker-compose.yml


version: '3'
services:
    db:
        #Use postgres for DB
        image: postgres
        #host's./tmp/with db/var/lib/postgresql/Synchronize data
        volumes:
            - ./tmp/db:/var/lib/postgresql/data
        #Specifying environment variables
        environment:
            POSTGRES_PASSWORD: password
    web:
        build: .
        #Server at container startup.Remove pid and run rails s
        command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
        #The current directory of the host is the container/Synchronize with myapp
        volumes:
            - .:/myapp
        #Port forwarding between host and container
        ports:
            - '3000:3000'
        #Dependencies between services
        depends_on:
            - db
        #Use Byebug in Docker environment
        stdin_open: true
        tty: true

Gemfile As for Gemfile, the one that is included by default is the main one. The added package is commented, so you can delete it if you don't need it.

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]
  #Introducing debug tools
  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'
  #Introducing auto-completion tools
  gem 'solargraph'
  #Introduction of static code analysis tool
  gem 'rubocop'
  gem 'rubocop-rails'
  #Introduction of erb format tool
  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 I added package.json because I want to use vue-router and vuex. If you want to use a UI framework such as Vuetify, add it.

package.json: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"
	}
}

Debug with Rails

Open a terminal on VScode Run the following in the terminal

VScode


docker-compose exec web rails console

pry starts

VScode


[1] pry(main)> 

create post controller

docker-compose exec web rails g controller post index

Modify post_controller.rb

post_controller.rb


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

model post

VScode


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

Reflect the model in DB

VScode


docker-compose exec web rails db:migrate

Rewrite index.html.erb as below

erb:index.html.erb


<%= @post.name %>
<%= @post.age %>

Modify routes.rb below

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

Create an instance of Post model with pry

VScode


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

#I haven't put any data in name or age yet
#Not even saved in DB
Post.all
=>   Post Load (2.2ms)  SELECT "posts".* FROM "posts"
[]

#Save the instance in 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 again.If you do all and get the data from the DB, the saved instance will be called.
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>]

#@Try putting data in the post instance
@post.name = "Hiro"
=> "Hiro"

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

#Save again
@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

#Data is stored
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>]

Access the following with a web browser

Web browser

http://localhost:3000

OK if you can get the data from DB as below

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

Try Binding.pry

Modify post_controller.rb

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

Access the following with a web browser

Web browser

http://localhost:3000

Freezes on the screen below (correct behavior) スクリーンショット 2020-09-23 22.30.19.png

Return to pry terminal

pry(main)> 

With the above, the environment for debugging with pry is ready.

reference

I referred to the following site. Docker Document Japaneseization Project Quick Start: Compose and Rails Dockerfile Best Practices Basic mechanism of Webpacker Let's create a development environment for "Rails / PostgreSQL" using Docker!

Recommended Posts

How to link Rails6 Vue (from environment construction)
[Environment construction] Uninstall rails from local
From 0 to Ruby on Rails environment construction [macOS] (From Homebrew installation to Rails installation)
[Rails] How to convert from erb to haml
How to build Rails 6 environment with Docker
How to build Rails + Vue + MySQL environment with Docker [2020/09 latest version]
How to write Rails
Rails Docker environment construction
How to uninstall Rails
Rails6.0 ~ How to create an eco-friendly development environment
Environment construction of Ruby on Rails from 0 [Cloud9] (From Ruby version change to Rails installation)
How to solve the local environment construction of Ruby on Rails (MAC)!
[Rails] How to build an environment with Docker
[Rails] How to use PostgreSQL in Vagrant environment
Deploy to Ruby on Rails Elastic beanstalk (Environment construction)
How to download images from AWS S3 (rails, carrierwave)
[Ruby on Rails] From MySQL construction to database change
Rails6 development environment construction [Mac]
[rails] How to post images
Rails engineer environment construction ruby2.7.1
Rails environment construction Rails5.2.1 ruby2.5.1 Catalina
[Rails] How to use enum
[Rails] How to install devise
Introduction to Metabase ~ Environment Construction ~
[Rails] How to use enum
How to read rails routes
How to use rails join
[Docker] Rails 5.2 environment construction with docker
How to terminate rails server
How to write Rails validation
How to write Rails seed
[Rails] How to use validation
[Rails] How to disable turbolinks
[Rails] How to use authenticate_user!
[Rails] How to use "kaminari"
[Rails] How to implement scraping
[Rails / MySQL] Mac environment construction
[Rails] How to make seed
How to write Rails routing
[Rails] How to install simple_calendar
[Rails] How to install reCAPTCHA
How to migrate from JUnit4 to JUnit5
[Rails] How to use Scope
How to set environment variables when using Payjp with Rails
How to write a migration from Rails datetime type to date type
How to build [TypeScript + Vue + Express + MySQL] environment with Docker ~ Express ~
How to set and describe environment variables using Rails zsh
How to build Rails, Postgres, ElasticSearch development environment with Docker
[Rails 5] How to use gem gon ~ How to pass variables from Rails to JS ~
[Rails5] japanMap link How to write parameters in js.erb file
[Docker context] ~ How to access docker in remote environment from VScode ~
[Rails] How to use gem "devise"
Rails + MySQL environment construction with Docker
How to deploy jQuery on Rails
[Rails] How to install Font Awesome
How to push from Tarminal to GitHub
[Rails] How to use devise (Note)
[Rails] How to use flash messages
[rails] How to display db information
[Rails] How to write in Japanese
[Rails] How to prevent screen transition