LoginSignup
78
89

More than 5 years have passed since last update.

RailsアプリにVue.jsを導入してみた(Vue.jsでRailsのDBを受け取る)

Last updated at Posted at 2019-01-16

最近Vue.jsを勉強しはじめて、
なんとかRuby on Railsで書いた既存アプリのフロント周りをなんとかVue.jsで書き直してみたので自分用メモとして残しておきます。

今回の目標

vuejs.gif

画像のようにECサイト上でジャンル一覧から任意のジャンルをクリックすると、
RailsのDBから呼び出されたジャンルごとのアーティストが描画されるようにする!

概要

どうやってこれを実装するのか
RailsのデータベースをVue.jsで受け取るにはそのまま変数で渡すことはもちろん出来ません。
なので、RailsでAPIを作ってaxiosのgetメソッドでそこを叩いてVue側で受け取ることで繋がります。

まずVue.jsの導入

今回は既存のRailsアプリに後からVueを入れるやり方です。
Gemfileに


gem "webpacker", github: "rails/webpacker”

を追記してbundle installします。

そしてターミナルで以下のコマンドを

$ bin/rails webpacker:install

コンパイル

$ bin/webpack

でコンパイルしておきましょう

コンパイルが失敗したときは

development.rb

process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const environment = require('./environment')

module.exports = Object.assign({}, environment.toWebpackConfig(), {
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }
})

をapp/config/development.rbに追記してください。

ここまででapp/javascript/packsというディレクトリが出来ているはずです。
今回はhello_vue.jsというファイルにコードを追記していきます。

Vueを読み込みましょう

application.html.erbのyieldの下に
を追加

application.html.erb
 <%= javascript_pack_tag "hello_vue" %>

APIの作成

今回hジャンルが選択されたら、そのジャンルのアーティストを配列で返すということをやりたいので、
Rails側のデータベースと連携させる必要があります。
なので

$ bundle exec rails g controller api::genres show

としてまずコントローラを作りましょう

ルーティングの追記

routes.rb
  namespace :api do 
    resources :genres, only: %i(show)
  end

API::GenresController

api/genres_controller
class GenresController < ApplicationController
  def show
    @genre = Genre.find(params[:id])
    @artists = Artist.where(genre_id: params[:id])
  end
end

ちなみにジャンルは複数のアーティストを持つので、
アソシエーションはGenre has_many artistsとなってます!

また、今回json形式で渡す必要があるのでjbuilderを使います。
app/views/api/genres/show.json.jbuilderに

show.json.jbuilder
json.genre_name @genre.genre_name
json.array do
  json.array! @genre.artists, :artist_name, :id
end

として、ジャンルごとのアーティスト一覧をarrayで渡しています。

APIの確認

/api/genres/1にアクセスすると
json.png
このようになっています。

ジャンルをクリックするたびにapi::genres_controllerが呼ばれて、クリックされたIDのジャンルがパラメータとして渡されています。

準備は整いました。

Vue.jsを書いていこう!

Vueのコード(hello_vue.js)


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

new Vue({
  el: ".genre_vue",
  data: {
    genreInfo: {},
    artists: [],
    showModal: false,
  },
  methods: {
    setGenreInfo(id){
      axios.get(`api/genres/${id}.json`)
      .then(res => {
        this.genreInfo = res.data;
        this.artists = res.data.array;
        this.showModal = true
      });
    },
    setArtistInfo(id){
     window.location.href = `artists/${id}`;
    }
  }
});

RailsのAPIからデータを持ってくるために冒頭でaxiosをimportしてます。
まずdataの中でartistsを空の配列で用意します。
axiosで自作APIからgenre別のartist配列を持ってきて、this.artistsに格納します。
setArtistInfoは無理やりアーティスト詳細ページにリンクを繋げたかっただけでもっといいやり方があるはずです。。

Railsのコード


<li v-for="artist in artists" v-on:click="setArtistInfo(artist.id)" class= "lime" v-bind:key="artist"> 
   {{ artist.artist_name }}
</li> 

先ほどVueの方でthis.artistsに格納された値をv-forディレクティブで回して
アーティストのアーティスト名をループさせています。

完成です!

次は検索機能を実装していきたいと思います。
現在は検索したらページ遷移させているのVueを用いて非同期で検索結果をレンダリングさせるようにします。

参照元

https://qiita.com/jnchito/items/30ab14ebf29b945559f6
https://qiita.com/cohki0305/items/582c0f5ed0750e60c951
https://qiita.com/cohki0305/items/a678b0b17c5b496c1de9

78
89
1

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
78
89