【问题标题】:Recursive accepts_nested_attributes_for in Rails, is it possible?Rails中的递归accept_nested_attributes_for,有可能吗?
【发布时间】:2021-12-29 19:43:49
【问题描述】:

我想在 Bar 和 Foo 这两个模型之间创建一个树形结构。

酒吧有很多 Foos

    Bar
  /  |  \
Foo Foo Foo
         ¦
        Bar
      /  |  \
    Foo Foo Foo

Bar 可以选择属于 Foo。

Bar 有许多 Foos,无穷无尽……

我配置了这样的东西,但它似乎没有正确播种。

即使我注释掉我拥有的任何验证,我也会收到以下错误:

ActiveRecord::RecordInvalid: Validation failed: Foos bar must exist

我不明白为什么。

class Bar < ApplicationRecord
  has_many :foos, inverse_of: :bar

  accepts_nested_attributes_for :foos
end


class Foo < ApplicationRecord
  belongs_to :bar, inverse_of: :foos

  accepts_nested_attributes_for :bar
end


class CreateFoos < ActiveRecord::Migration[6.1]
  def change
    create_table :foos do |t|
      t.text :description, null: false

      t.timestamps
    end
  end
end

class CreateBars < ActiveRecord::Migration[6.1]
  def change
    create_table :bars do |t|
      t.text :description

      t.references :foo,
        foreign_key: true,
        null: true,
        on_delete: :cascade,
        on_update: :cascade

      t.timestamps
    end
  end
end

class AddBarIdToFoosTable < ActiveRecord::Migration[6.1]
  def change
    add_reference :foos,
      :bar,
      foreign_key: true,
      null: false,
      on_delete: :cascade,
      on_update: :cascade
  end
end


Bar.create!([
  {
    description: 'Lorem ipsum...',
    foos_attributes: [
      {
        description: 'Lorem ipsum...',
        bar_attributes: {
          description: 'Lorem ipsum...',
          foos_attributes: [
            {
              description: 'Lorem ipsum...',
              bar_attributes: {
                description: 'Lorem ipsum...',
                foos_attributes: [
                  {
                    description: 'Lorem ipsum...'
                  },
                  {
                    description: 'Lorem ipsum...'
                  },
                  {
                    description: 'Lorem ipsum...'
                  },
                  {
                    description: 'Lorem ipsum...'
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  }
])

【问题讨论】:

  • 为什么在 Foo 中需要 Accepts_nested_attributes?用 bar 创建一个 foo 只需将 bar_id 传递给 foo
  • 这个逻辑感觉很循环,我很难理解现实世界的应用程序会是什么。为什么要使用两个不同的模型来定义同一个对象(即树中的一个节点)? IMO 每个元素(foo 或 bar)都应该属于您的节点模型。这是一个您可能会发现有用的随机博客:leighhalliday.com/tree-structures-in-your-rails-models
  • @Allison 您在这里看到的并不是我正在尝试做的一对一映射。所涉及的模型有其特殊的区别,我需要保持分开
  • @Mosaaleb 是的,这是一个好点,我对 Rails 不是最熟悉,是从另一个框架过来的,所以我还没有完全搞清楚,我会尝试在其他修改中删除它
  • 在我看到这个之前删除了我的评论以支持回答,但如果您有严格的父子关系,您可能希望在两个类上同时定义 belongs_tohas_many,以及 Rails如果您以前没有遇到过指南,那么指南非常好:guides.rubyonrails.org/association_basics.html

标签: ruby-on-rails ruby recursion ruby-on-rails-6 accepts-nested-attributes


【解决方案1】:

ActiveRecord::RecordInvalid: Validation failed: Foos bar must exist

  • 这告诉您,您的 Foo 声明之一需要存在 bar
  • 在 Foo 的模型声明中对 bar 的引用位于 belongs_to 关联中
  • belongs_to 在某些版本的 Rails 中默认是存在验证的;将 belongs_to :bar 更改为 belongs_to :bar, optional: true 可能会解决您的问题

参考:https://github.com/rails/rails/pull/18937/files

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-17
    • 2014-04-20
    • 2012-02-08
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多