我试图在Rails应用程序中使用Vue.js创建嵌套表单。我使用嵌套表格将配料保存到配方中。现在,配料中的所有东西都会保存,但配料的名称(从输入字段中取出)。如何将此名称字段保存到数据库中?
应用/模型/ ingredient.rb
class Ingredient < ApplicationRecord
belongs_to :recipe
end
应用/模型/ recipe.rb
class Recipe < ApplicationRecord
has_many :ingredients
end
应用/视图/ index.html.erb
<h1>Index</h1>
<div id="app">
{{ message }}
<form>
<div class="form-group">
<label class="form-label">Name</label>
<input class="form-control" type="text" placeholder="Recipe's Name" v-model="recipe.name">
</div>
<div class="form-group">
<label class="form-label">Chef</label>
<input class="form-control" type="text" placeholder="Chef's Name" v-model="recipe.chef">
</div>
<div class="form-group">
<label class="form-label">Cooktime</label>
<select class="form-control" type="text" v-model="recipe.cooktime">
<option v-for="cookingtime in cookingtimes" :value="cookingtime.value">
{{ cookingtime.cook }}
</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Serves</label>
<select class="form-control" type="text" v-model="recipe.amount">
<option v-for="serving in servings" :value="serving.value">
{{ serving.serves }}
</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Description</label>
<textarea class="form-control" rows="5" placeholder="Recipe Description" v-model="recipe.description"></textarea>
</div>
<div class="form-group">
<label class="form-label">Favorite</label>
<input type="checkbox" v-model="recipe.favorite">
</div>
<button class="btn btn-default" type="button" @click="newIngredient">Add Ingredient</button>
<div class="form-group" v-for="(ingredient, index) in recipe.ingredients">
<label class="form-label">Ingredient</label>
<input type="text" v-model="ingredient.name">
<a @click="removeIngredient(index)">Remove Ingredient</a>
<p>Ingredient: {{ ingredient }}</p>
<p>Index: {{ index }}</p>
</div>
<div id="recipe-index-submit-button-container">
<button type="submit" class="btn btn-default" @click="newRecipe">Submit</button>
</div>
</form>
</div>
应用/视图/ API / V1 /食谱/ index.json.jbuilder
json.array! @recipes, partial: "recipe", as: :recipe
应用/视图/ API / V1 /食谱/ _recipe.json.jbuilder
json.id recipe.id
json.name recipe.name
json.chef recipe.chef
json.cooktime recipe.cooktime
json.amount recipe.amount
json.description recipe.description
json.favorite recipe.favorite
json.user_id recipe.user_id
json.ingredients do
json.array!(recipe.ingredients) do |ingredient|
json.ingredient_id ingredient.id
json.ingredient_name ingredient.name
json.ingredient_recipe_id ingredient.recipe_id
end
end
应用/控制器/ API / V1 / recipes_controller.rb
class Api::V1::RecipesController < ApplicationController
def index
@recipes = Recipe.all
end
def create
@recipe = Recipe.new(recipe_params)
@recipe.ingredients.build
if @recipe.save
render :show
else
render json: { errors: @recipe.errors.full_messages }, status: 422
end
end
def show
@recipe = Recipe.find_by(id: params[:id])
end
private
def recipe_params
params.require(:recipe).permit(
:name,
:chef,
:cooktime,
:amount,
:description,
:favorite,
:user_id,
ingredients:[
:id,
:name,
:recipe_id
]
)
end
end
应用/ Javascript角/ recipes_ctrl.js
$(document).on('ready', function() {
new Vue({
el: '#app',
data: {
message: "Hello World!",
recipe: {
name: '',
chef: '',
cooktime: '',
amount: '',
description: '',
favorite: false,
ingredients: [
{name: ''},
]
},
recipes: [],
errors: {},
cookingtimes: [
{cook: "less than 15 minutes", value: "less than 15 minutes"},
{cook: "15 minutes", value: "15 minutes"},
{cook: "30 minutes", value: "30 minutes"},
{cook: "45 minutes", value: "45 minutes"},
{cook: "1 hour", value: "1 hour"},
{cook: "1 hour 30 minutes", value: "1 hour 30 minutes"},
{cook: "2 hours", value: "2 hours"},
{cook: "2 hours 30 minutes", value: "2 hours 30 minutes"},
{cook: "3 hours", value: "3 hours"},
{cook: "3 hours 30 minutes", value: "3 hours 30 minutes"},
{cook: "4 hours", value: "4 hours"},
{cook: "more than 4 hours", value: "more than 4 hours"}
],
servings: [
{serves: "1", value: 1},
{serves: "2", value: 2},
{serves: "3", value: 3},
{serves: "4", value: 4},
{serves: "5", value: 5},
{serves: "6", value: 6},
{serves: "7", value: 7},
{serves: "8", value: 8},
{serves: "9", value: 9},
{serves: "10", value: 10},
{serves: "11", value: 11},
{serves: "12", value: 12},
{serves: "more than 12", value: "more than 12"}
]
},
methods: {
newRecipe: function(){
this.$http.post('/api/v1/recipes.json', this.recipe).then(function(response){
this.recipes.push(this.recipe);
}).catch(function(response){
this.errors = response.data.errors;
});
console.log("this.recipe " + this.recipe);
},
newIngredient: function(){
this.recipe.ingredients.push({name:'', recipe_id: ''});
},
removeIngredient: function(index){
console.log("index " + index);
this.recipe.ingredients.splice(index, 1);
}
}
})
})
这是终端向我展示的内容。我现在也将我的应用程序控制器设置为空会话。
Processing by Api::V1::RecipesController#create as JSON
Parameters: {"name"=>"", "chef"=>"", "cooktime"=>"", "amount"=>"", "description"=>"", "favorite"=>false, "ingredients"=>[{"name"=>"test"}, {"recipe_id"=>""], "recipe"=>{"name"=>"", "chef"=>"", "cooktime"=>"", "amount"=>"", "description"=>"", "favorite"=>false}}
Can't verify CSRF token authenticity.
(4.3ms) BEGIN
SQL (5.5ms) INSERT INTO "recipes" ("name", "chef", "cooktime", "description", "favorite", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["name", ""], ["chef", ""], ["cooktime", ""], ["description", ""], ["favorite", false], ["created_at", 2017-02-05 17:29:34 UTC], ["updated_at", 2017-02-05 17:29:34 UTC]]
SQL (51.5ms) INSERT INTO "ingredients" ("recipe_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["recipe_id", 18], ["created_at", 2017-02-05 17:29:34 UTC], ["updated_at", 2017-02-05 17:29:34 UTC]]
(3.1ms) COMMIT
Rendering api/v1/recipes/show.json.jbuilder
Ingredient Load (0.7ms) SELECT "ingredients".* FROM "ingredients" WHERE "ingredients"."recipe_id" = $1 [["recipe_id", 18]]
Rendered api/v1/recipes/_recipe.json.jbuilder (12.2ms)
答案 0 :(得分:1)
我认为您在@recipe.ingredients.build
操作中不需要create
,并且以这种方式保存,您需要将accepts_nested_attributes_for :ingredients
添加到Recipe