1 分鐘閱讀

介紹

本文為 GoRails 的 Using VueJS for Nested Forms with Rails 練習 有興趣可以參考影片及git Video Part1 Video Part2 Git

準備工作

  1. 更新到 Rails 5.1
  2. 先安裝好npm

安裝新專案

$ rails new gorails --webpack=vue
$ git add .
$ git commit -m "initial commit"
$ git checkout -b 'episode-184'  #開個新branch做此專案

補上jQuery

因為rails 5 取消了原本預設的jQuery 這邊建議還是先補上來,因為很多舊gem還沒把底層改為javascript

# [path] gemfile
gem 'jquery-rails'
// [path] application.js
//= require rails-ujs
//= require turbolinks
//= require jquery
$ bundle install

建立model

此範例使用team及player來做nested from

$ rails g model team name
$ rails g model player name position team:belongs_to
$ rake db:migrate

補上關聯及接受nested form

# [path] team.rb
class Team < ApplicationRecord
  has_many :players, dependent: :destroy
  accepts_nested_attributes_for :players, allow_destroy: true
end

建立Controller及View

這邊使用scaffold_controller快速搭建一個基本的team的CRUD (在已存在model時建立scaffold)

$ rails g scaffold_controller team name

補上player_attributes的params

# [path] team_controller.rb
def team_params
  params.require(:team).permit(:name, players_attributes: [:id, :name, :position, :_destroy])
end

建立route

# [path] routes.rb
resources :teams
root "teams#index"

調整vue進入點

// [path] hello_vue.js
import Vue from 'vue/dist/vue.esm'
import TurbolinksAdapter from 'vue-turbolinks'
import VueResource from 'vue-resource'

Vue.use(VueResource)

document.addEventListener('turbolinks:load', () => {
  Vue.http.headers.common['X-CSRF-Token'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
  var element = document.getElementById('team-form')
  if (element != null){
    var team = JSON.parse(element.dataset.team)
    var players_attributes = JSON.parse(element.dataset.playersAttributes)
    players_attributes.forEach(function(player){ player._destroy = null})
    team.players_attribute = players_attributes

    var app = new Vue({
      el: element,
      mixins: [TurbolinksAdapter],
      data: function(){
        return { team: team }
      }
    })

    console.log(app);
  }
})
<!-- [path] app.vue -->
<%= content_tag :div,
  id: 'team-form',
  data: {
    team: team.to_json(except: [:created_at, :updated_at]),
    players_attributes: team.players.to_json(except: [:team_id, :created_at, :updated_at]),
  } do %>

<label for="">Team name</label>
<input type="text" v-model="team.name" >

<% end %>
$ yarn add vue-resource
$ yarn add vue-turbolinks
$ rails webpacker:compile
$ ./bin/webpack-dev-server
$ rails s 

參考

  1. Video Part1
  2. Video Part2
  3. Git
  4. https://medium.com/@hpux/rails-5-1-loves-javascript-a1d84d5318b

更新時間:

留言