【问题标题】:Deleting a parent object if no child is created to match it's ID如果没有创建子对象以匹配其 ID,则删除父对象
【发布时间】:2018-06-14 17:17:21
【问题描述】:

如果没有创建子对象,是否有一种简单的方法可以追溯删除父对象?

has_many 和 belongs_to 关系。

我想保持我的 parent.id 和 child.parent_id 同步,如果我的父对象持续存在,并且没有创建子对象,我将留下异步 ID。

有什么帮助吗?

我保留这个一般性并寻找一般性答案!

【问题讨论】:

    标签: ruby-on-rails ruby database activerecord


    【解决方案1】:

    我不确定您所说的保持 id '同步'是什么意思。如果您像这样使用父级来创建子级:parent.children.create(attributes),它们应该永远不会不同。

    不过,听起来好像您正在做的是先创建父级,然后是子级,但都在同一个动作中。但是,有时由于验证失败或其他原因而没有创建子级,并且您也不希望创建父级。有几种方法可以做到这一点。

    最干净的是accepts_nested_attributes

    型号:

    class Parent
      has_many :children, inverse_of: parent
      accepts_nested_attributes_for :children
    end
    
    class Child
      belongs_to :parent, inverse_of :children
    end
    

    控制器

    ParentController
      def create
        parent.create(parent_params)
      end
    
      def parent_params
        params.require(:parent).permit(:parent_attribute_1, :parent_attribute_2, :children_attributes => [:child_attribute_1, etc.])
      end
    end
    

    您的参数必须像上面的结构一样嵌套,但它允许父级接受子级的属性并同时实例化和创建两者。

    或者,您可以在事务块内同时创建父子节点和子节点,如果抛出异常,它将回滚所有已完成的事务。因此,您可以使用save!create! 方法来确保只有在事务块内的所有内容都正常工作时,事务才会完成。

    【讨论】:

    • 您好,感谢您的帮助!我会检查一下。你是对的,我首先创建父级,但我的验证很好。不好的是,如果有人单击将他们从子表单页面带走的链接,这会导致父对象持续存在,但没有子对象这将增加父 ID,但自然不会有 child.parent_id正在创建(或相关的 ID)
    • 如果有必要一次发布所有参数,我会在前端使用向导之类的东西一次创建所有内容。在你也有孩子之前不要创建父母。
    • 我注意到这可能与您昨天发布的“嵌套表单:如果第二个表单留空,则删除两个对象”相同的问题?如果是这样,我肯定会在前端使用某种带有嵌套表单的向导库。查看guides.rubyonrails.org/form_helpers.html#configuring-the-model
    • 嘿,谢谢以赛亚,我会调查的。是的,我昨天发布了它,它没有被点击...我想我会尝试一种更通用的方法来解决我的问题。感谢您的帮助!
    • 感谢您的帮助。我没有完全解决如何删除父级,实际上,出于功能原因,它可以解决。困扰我的是ID的不匹配。我通过在创建时简单地将 parent.id 分配给新的 child.id 来解决这个问题。没有更多的 IDS 不匹配!你让我进入了一个很好的兔子洞,这导致了一个解决方案。谢谢你
    【解决方案2】:

    让活动记录验证完成您的工作。你知道你可以做这样的事情吗:

    class Teacher < ActiveRecord::Base
      has_many :teacher_students
      has_many :students, :through => :teacher_students
      validates :students, :length => { :minimum => 1 }
    end
    

    或者如果您不想在创建时验证它:

    class Teacher < ActiveRecord::Base
      has_many :teacher_students
      has_many :students, :through => :teacher_students
      validates :students, :length => { :minimum => 1 }, on: :update
    end
    

    【讨论】:

    • 感谢您的回复!不幸的是,就我而言,这将阻止首先创建父级。有什么建议可以解决这个问题吗?
    • 在创建操作中尝试@teacher.save(validate: false)。这将跳过验证。
    • @TylerP3358 或者您可以尝试我在更新答案中提供的替代解决方案
    • 谢谢 Abhilash,我会在这里尝试一下!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2019-11-25
    • 1970-01-01
    • 2018-12-27
    相关资源
    最近更新 更多