【问题标题】:Rails4 ActiveRecord Association: create a parent and child record at the same time using a nested form?Rails4 ActiveRecord 关联:使用嵌套表单同时创建父子记录?
【发布时间】:2016-01-08 00:14:05
【问题描述】:

我一直在努力让它工作一段时间,如果有人可以让我知道我是否走在正确的道路上或向我指出一些可能有帮助的文档,我将不胜感激。:

我有两个活动记录模型,Parent.rb 和 Child.rb(设置了 belongs_to: parent)。 我正在尝试同时创建父记录和子记录并将它们关联(这样如果子记录无效,则根本不会创建父记录)。

以下是我目前所拥有的:

create_child.haml

= be_form_for @child do |f|
  = ff.text_field :name, 'child name'
  = f.fields_for :parent do |ff|
    = ff.text_field :name, 'parent name'

  = f.submit_tag 'Create'

children_controller.rb children_controller.rb

def create
  Parent.create(child_params[:parent])
  Child.create(child_params)
end

def child_params
  params.require(:child).permit(:name, :parent)
end

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    此代码中缺少很多内容。 railscasts.com 是一个旧资源,但此链接涵盖了仍在使用的想法。

    http://railscasts.com/episodes/196-nested-model-form-part-1

    总体思路:

    • 为父模型创建一个表单,然后将子(ren)的字段放入其中
    • 使用accepts_nested_attributes_for,它会自动创建两个对象并在一个无效时显示错误
    • 我认为您可以强制孩子遵守形式,但我认为这不是自然秩序
    • 创建方法需要一些验证,请遵循 Rails 指南中关于标准行为的说明

    如下图所示

    def create @parent = Parent.new(parent_params) # params include child params as well, accepting nested attributes resolves that if @parent.save redirect_to root_path else render 'new' end end

    【讨论】:

      【解决方案2】:

      我知道你或多或少想做什么,这将是我的建议,尽可能“最可靠”的方式:

      class Parent < ActiveRecord::Base
          has_one :child
      
          validates :name, presence: true
          validates :age, presence: true
      end
      
      class Child < ActiveRecord::Base
          belongs_to :parent
      
          validates :name, presence: true
          validates :age, presence: true
          validates :favorite_color, presence: true
      end
      
      
      class ParentsController < ApplicationController
          # Display the form and initialize the form variables
          def new
              @parent = Parent.new
              @parent.build_child  #=> use if has_one relationship
              @parent.childs.build #=> use if has_many relationship
          end
      
          def create
              @parent = Parent.new(parent_params)
      
              if @parent.save
                  flash[:notice] = "Parent and child were successfully saved."
                  redirect_to some_path
              else
                  flash[:error] = "Could not create parent and child."
                  render :new
              end
          end
      
          private
          def parent_params
              params.require(:parent).permit(:name, :age, child_attributes: [:name, :age, :favorite_color])
          end
      end
      

      在您看来(因为您使用的是haml):

      = form_for @parent do |f|
        = f.text_field :name
        = f.text_field :age
      
        / Here's the magic
        = f.fields_for :child do |c|
          = c.text_field :name
          = c.text_field :age
          = c.text_field :favorite_color
      
          = f.submit :submit
      

      如果您为两个模型添加正确的验证,当在您的视图中使用 fields_for 方法时,只要 Child 和 Parent 验证通过,Rails 就不会保存 Parent 或 Child。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多