[Rails] Using VueJS for Nested Forms with Rails
介紹
本文為 GoRails 的 Using VueJS for Nested Forms with Rails 練習 有興趣可以參考影片及git Video Part1 Video Part2 Git
準備工作
- 更新到 Rails 5.1
- 先安裝好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
參考
- Video Part1
- Video Part2
- Git
- https://medium.com/@hpux/rails-5-1-loves-javascript-a1d84d5318b
留言