MyFirstRails

Blog サンプル

概要

Railsにこれから初めて触れる方を対象にしたチュートリアルです RailsとVue.jsを使ってSPA(シングルページアプリケーション)のサンプルを作成します

チュートリアル

Railsのひな型を作る

まず、rails newを実行し、Railsアプリのひな型を作成します。

rails new spa --webpack=vue

--webpackはRailsでWeboackを使いやすくしたWebpackerというものを使用するというオプションです

Vue、React、Angular、Elm、Stimulusを使用することができます

今回はVue.jsを使用するので--webpack=vueとしています

次に、作成したRailsアプリのディレクトリへと移動します。

cd spa

Foremanを使う

Webpackerを使う場合、ruby ./bin/webpack-dev-serverというコマンドを実行しつつ、rails sでローカルサーバーを起動する必要があります

その為、現状のままではターミナルを複数開いておく必要があり、少々面倒です

そこで、複数のコマンドを並列して実行できるforemanを使用します

まず、Gemfilegem 'foreman'を追記します

gem 'foreman'

その後、bundle install

bundle install

次に、foremanで使用するProcfile.devを作成します

web: bundle exec rails s
webpacker: ruby ./bin/webpack-dev-server

あとは、foreman start -f Procfile.devをターミナルで実行するだけです

foreman start -f Procfile.dev

localhost:5000にアクセスできればOkです(foremanを使用する場合、使用するポートが5000へと変更されています)

静的なファイルを作成

rails g controller コマンドを使い、静的なファイルを作成します

rails g controller web index

foreman start -f Procfile.devを実行して、localhost:5000/web/indexにアクセスできればOKです

Vue.jsを使う

app/javascript/packsディレクトリ内にindex.jsを作成します

app/javascript/packs/index.jsを以下のように変更します

import Vue from 'vue/dist/vue.esm';

const app = new Vue({
    el: '.app',
    data: function() {
        return {
            message: "Hello World! For Vue.js & Rails!"
        }
    }
})

次に、app/views/web/index.html.erbを以下のように変更します

<div class="app">
    
</div>

<%= javascript_pack_tag 'index' %>

foreman start -f Procfile.devを実行して、localhost:5000/web/indexにアクセスします 画面にHello World! For Vue.js & Rails!と表示されていればOKです

Bootstrapの導入

Webpackerを使用する場合は、JavaScriptパッケージマネージャのyarn経由でBootstrapをインストールします

yarn add bootstrap

付随して、jquerypopper.jsもインストールします

yarn add jquery
yarn add popper.js

次に、app/javascript/packs/index.jsapp/assets/stylesheets/application.cssを以下のように変更します

import Vue from 'vue/dist/vue.esm';
import * as Bootstrap from 'bootstrap';
import 'bootstrap/dist/css/bootstrap';

Vue.use(Bootstrap);

const app = new Vue({
    el: '.app',
    data: function() {
        return {
            message: "Hello World! For Vue.js & Rails!"
        }
    }
})
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require bootstrap/dist/css/bootstrap
 *= require_tree .
 *= require_self
 */

これでBootstrapが使用できるようになります

では、実際にナビゲーションバーを作成してみます

app/javascript/packs/components/layouts/Header.vueを作成します

<template>
    <div>
        <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
            <a class="navbar-brand" href="#">SPA</a>
            <div class="dropdown">
                <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    Menu
                </button>
                <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
                    <a href="/" class="dropdown-item">Top</a>
                    <a href="/about" class="dropdown-item">About</a>
                    <a href="/contact" class="dropdown-item">Contact</a>
                </div>
            </div>
        </nav>
    </div>    
</template>

app/views/web/index.html.erbapp/javascript/packs/index.jsを以下のように変更します

<div class="app">
    <nav-bar></nav-bar>
    
</div>

<%= javascript_pack_tag 'index' %>
import Vue from 'vue/dist/vue.esm';
import * as Bootstrap from 'bootstrap';
import 'bootstrap/dist/css/bootstrap';

import Header from './components/layouts/Header.vue';

Vue.use(Bootstrap);

const app = new Vue({
    el: '.app',
    components: {
        'nav-bar': Header
    },
    data: function() {
        return {
            message: "Hello World! For Vue.js & Rails!"
        }
    }
})

foreman start -f Procfile.devでローカルサーバを起動して、localhost:5000/web/indexを開きます ナビゲーションバーが表示されていると思います

vue-routerによるSPA作成

まず、SPAとして表示する書くページをapp/javascript/packs/components/webディレクトリに作成します

<template>
    <div class="container">
        <h1>Index Pages</h1>

        <p>ここはIndexページです!</p>
    </div>    
</template>
<template>
    <div class="container">
        <h1>About Pages</h1>

        <p>ここはAboutページです!</p>
    </div>    
</template>
<template>
    <div class="container">
        <h1>Contact Pages</h1>

        <p>ここはContactページです!</p>
    </div>    
</template>

各ページのコンポーネントを作成後、yarn add vue-routervue-routerをインストールします

yarn add vue-router

次に、app/javascript/packs/router/router.jsを作成します

import Vue from 'vue/dist/vue.esm';
import VueRouter from 'vue-router';

import Index from '../components/web/Index.vue';
import About from '../components/web/About.vue';
import Contact from '../components/web/Contact.vue';

Vue.use(VueRouter);

export default new VueRouter({
    mode: 'history',
    routes: [
        { path: '/', component: Index },
        { path: '/about', component: About },
        { path: '/contact', component: Contact }
    ]
})

最後に、app/javascript/packs/index.jsapp/views/web/index.html.erbconfig/routes.rbを以下のように編集します

import Vue from 'vue/dist/vue.esm';
import * as Bootstrap from 'bootstrap';
import 'bootstrap/dist/css/bootstrap';

import Header from './components/layouts/Header.vue';
import Router from './router/router';

Vue.use(Bootstrap);

const app = new Vue({
    el: '.app',
    router: Router,
    components: {
        'nav-bar': Header
    },
    data: function() {
        return {
            message: "Hello World! For Vue.js & Rails!"
        }
    }
})
<div class="app">
    <nav-bar></nav-bar>
    <div class="container">
        <router-view></router-view>
    </div>
    
</div>

<%= javascript_pack_tag 'index' %>
Rails.application.routes.draw do
  root 'web#index'
  get '/about', to: 'web#index'
  get '/contact', to: 'web#index'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

これで、SPAサンプルが作成できました!