Rails4 ActiveRecord Association:使用嵌套表单同时创建父记录和子记录?

时间:2016-01-08 00:14:06

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

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

我有两个活动记录模型,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

2 个答案:

答案 0 :(得分:1)

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

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

作为一般概念:

  • 为父模型创建一个表单,然后将子(ren)字段放在
  • 使用accepts_nested_attributes_for,它会自动创建两个对象并在一个无效时显示错误
  • 我认为你可以在表格上强制执行一个孩子,但我认为这不是自然的顺序
  • create方法需要进行一些验证,请遵循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

答案 1 :(得分:1)

我知道你或多或少会尝试做什么,而这将是我的建议,因为这是最好的" railsiest"可能的方式:

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就不会保存父或子。