簡體   English   中英

如何從父級創建子模型

[英]How to create a child model from a parent

我已經旋轉了幾天就可以用Rails轉動輪子了。 我正在使用三種模型: IngredientBaseIngredientIngredientList IngredientBase包含可能是“雞”,“雞蛋”或“培根”的字符串。 成分將具有單一Ingredient和數量。 IngredientList將有許多成分。

我希望用戶能夠使用ingredient_lists / new並能夠在提交IngredientList之前創建多個IngredientList 如果沒有用戶提交多個表單,我怎么能這樣做?

聯想

你正在看的是嵌套模型

嵌套模型基本上允許您將屬性附加到一個模型的實例; 那些屬性被發送到關聯模型。

這是通過accepts_nested_attributes_for實現的:

#app/models/ingredient_list.rb
class IngrendientList < ActiveRecord::Base
   has_many :ingredients
   accepts_nested_attributes_for :ingredients
end

#app/models/ingredient.rb
class Ingredient < ActiveRecord::Base
   belongs_to :ingredient_list
end

因為你的模型讓我困惑,我為你重寫了結構。 我認為你對連接模型等感到困惑:

#app/models/ingredient.rb
class Ingredient < ActiveRecord::Base
   #columns id | name | weight | etc | created_at | updated_at
   has_many :recipe_ingredients
   has_many :recipes, through: :recipe_ingredients
end

#app/models/recipe_ingredient.rb
class RecipeIngredient < ActiveRecord::Base
    #columns id | recipe_id | ingredient_id | quantity | created_at | updated_at
    belongs_to :recipe
    belongs_to :ingredient
    accepts_nested_attributes_for :ingredient
end

#app/models/recipe.rb
class Recipe < ActiveRecord::Base
   #columns id | name | etc | etc | created_at | updated_at
   has_many :recipe_ingredients #-> allows extra attributes
   has_many :ingredients, through: :recipe_ingredients 
   accepts_nested_attributes_for :recipe_ingredients
end

這將使您能夠創建Recipe ,添加新的Ingredient ,並通常使您的模型更加健壯。

以下是如何使它與控制器和視圖等一起使用:

#app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
   def new
      @recipe = Recipe.new
   end
   def create
      @recipe = Recipe.new recipe_params
      @recipe.save
   end

   private

   def recipe_params
      params.require(:recipe).permit(:recipe, :params, recipe_ingredients_attributes: [:quantity, ingredient_attributes:[:name]])
   end
end

這將創建一個基本表單,但我們需要包含相關字段。 有幾種方法可以做到這一點,包括RailsCasts的“手動”方法和使用Cocoon

因此,需要注意的重要事項是:

每次調用嵌套表單字段時,基本上都是讓Rails將f.fields_for另一個實例添加到表單中。 這里要注意的重要的事情是你需要具備的CHILD_INDEX fields_for塊。 這是Rails用於識別字段的內容,需要保持唯一。

你可以在一段時間內回答的問題上看到更多相關信息。

對於您的表單,您需要以下內容:

#app/views/recipes/new.html.erb
<%= form_for @recipe do |f| %>
   <%= f.text_field :title %> 
   <%= render "ingredients", locals: {f: f, child_index: Time.now.to_i}  %>
   <%= link_to "Add Ingredient", recipes_add_field_path, class: "ingredient" %>
   <%= f.submit %>
<% end %>

#app/views/recipes/_ingredients.html.erb
<%= f.fields_for :recipe_ingredients, child_index: child_index do |ri| %>
    <%= ri.text_field :quantity %>
    <%= ri.fields_for :ingredient do |ingredient| %>
       <%= ingredient.text_field :name %>
       <%= ingredient.text_field :weight %>
    <% end %>
<% end %>

#config/routes.rb
resources :recipes do
   member "add_field", to: "recipes#add_field"
end

#app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
   def add_field
      @recipe = Recipe.new
      @recipe.recipe_ingredients.build.build_ingredient
      render "new"
   end
end

#app/assets/javascripts/application.js
$(document).on("click", "a.ingredient", function(){
   $.ajax({
      url: '/recipes/add_field',
      success: function(data){
        el_to_add = $(data).html();
        $('#recipes').append(el_to_add);
      }
      error: function(data){
         alert("Sorry, There Was An Error!");
      }
   });
});

處理嵌套關系的最佳方法是使用accept_nested_attributes

為了更好地理解這里是一個鏈接

而在這里管理ui級別的形式是一個寶石

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM