我通过观看gorails tutorial创建了一个嵌套表单,这很好,我做到了。当我想在其他嵌套模型下创建嵌套模型时,问题开始了。我有Survey
模型,它是主要模型。然后,我添加了Question
模型并使用vue.js制作了表格。因此,我在问题中添加了Choice
模型(您可以在测量控制器参数中注意到)第一个问题是;我不知道如何在vue.js控件中定义/实现。(hello_vue.js)第二个要点是:如何在new.html中创建表单元素
这是我的survey.rb模型:
class Survey < ApplicationRecord
has_many :questions, dependent: :destroy
accepts_nested_attributes_for :questions, allow_destroy: true
belongs_to :user
end
and surveys_controller.rb
class SurveysController < ApplicationController
before_action :set_survey, only: [:show, :edit, :update, :destroy]
def survey_params
params.require(:survey).permit(:user_id, :name, questions_attributes:[:id,:survey_id, :title, :qtype, :_destroy, choices_attributes:[:id,:question, :ctext]])
end
end
这是Survey的嵌套模型:question.rb:
class Question < ApplicationRecord
enum qtype: [:multiple_choice, :check_boxes, :short_answer]
belongs_to :survey
has_many :choices
accepts_nested_attributes_for :choices, allow_destroy: true
end
最后的vue.js文件:
import TurbolinksAdapter from 'vue-turbolinks'
import Vue from 'vue/dist/vue.esm'
import VueResource from 'vue-resource'
Vue.use(VueResource)
Vue.use(TurbolinksAdapter)
Vue.component('app', App)
document.addEventListener('turbolinks:load', () => {
Vue.http.headers.common['X-CSRF-Token'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
var element = document.getElementById("survey-form")
if (element != null){
var survey = JSON.parse(element.dataset.survey)
var questions_attributes = JSON.parse(element.dataset.questionsAttributes)
var choices_attributes = JSON.parse(element.dataset.choicesAttributes)
questions_attributes.forEach(function(question) { question._destroy = null })
survey.questions_attributes = questions_attributes
var app = new Vue({
el: element,
//mixins: [TurbolinksAdapter],
data: function(){
return { survey: survey }
},
methods:{
addQuestion: function(){
this.survey.questions_attributes.push({
id: null,
title:"",
qtype:"",
_destroy: null
})
},
removeQuestion: function(index) {
var question = this.survey.questions_attributes[index]
if (question.id == null) {
this.survey.questions_attributes.splice(index, 1)
} else {
this.survey.questions_attributes[index]._destroy = "1"
}
},
undoRemove: function(index) {
this.survey.questions_attributes[index]._destroy = null
},
saveSurvey: function() {
// Create a new survey
if (this.survey.id == null) {
this.$http.post('/surveys', { survey: this.survey }).then(response => {
Turbolinks.visit(`/surveys/${response.body.id}`)
}, response => {
console.log(response)
})
// Edit an existing survey
} else {
this.$http.put(`/surveys/${this.survey.id}`, { survey: this.survey }).then(response => {
Turbolinks.visit(`/surveys/${response.body.id}`)
}, response => {
console.log(response)
})
}
},
existingSurvey: function() {
return this.survey.id != null
}
}
})
}
})
_form.html.erb
<%= content_tag :div,
id: "survey-form",
data: {
survey: survey.to_json(except: [:created_at, :updated_at]),
questions_attributes: survey.questions.to_json,
} do %>
<label>Survey Name</label>
<input qtype="text" v-model="survey.name">
<h4>Questions</h4>
<div v-for="(question, index) in survey.questions_attributes">
<div v-if="question._destroy == '1'">
{{ question.title }} will be removed. <button v-on:click="undoRemove(index)">Undo</button>
</div>
<div v-else>
<label>Question</label>
<input qtype="text" v-model="question.title" />
<label>Qestion qtype</label>
<select v-model="question.qtype">
<option v-for="qtype in <%= Question.qtypes.keys.to_json %>"
:value=qtype>
{{ qtype }}
</option>
</select>
<button v-on:click="removeQuestion(index)">Remove</button>
</div>
<hr />
</div>
<button v-on:click="addQuestion">Add Question</button>
<br>
<button v-on:click="saveSurvey" >Save Survey</button>
<% end %>
答案 0 :(得分:1)
我遵循了相同的教程,并开始使用带有更复杂的嵌套属性的JSON.parse遇到问题。尝试使用Jbuilder构建JSON对象,并查看gon gem以将Rails变量传递到Javascript中。使用Rails所需的嵌套命名,查询数据库并将结果传递到Javascript文件将更加容易。例如...
survey = @survey
json.id survey.id
json.survey do
json.(survey, :user_id, :name)
json.questions_attributes survey.questions do |question|
json.(question, :id, :title, :qtype, :_destroy)
json.choices_attributes question.choices do |choice|
json.(choice, :id, :ctext)
end
end
end
它允许您执行类似...
var survey = gon.survey
而不是...
var survey = JSON.parse(element.dataset.survey)
您可以通过控制器操作传递gon.jbuilder
,并准备好定义的JSON对象并在Vue中可用。