嵌套`accepts_nested_attributes_for`使用_indifferent_access'`

时间:2018-03-14 00:56:49

标签: ruby-on-rails-5

我正在编写用于创建新帐户的规范。情况如下:

Ruby 2.5.0,Rails 5.2.0.rc1

class Account
  has_many :accounts_users, inverse_of: :account
  has_many :users, through: :accounts_users
  has_one :owner, -> { AccountsUser.admins.order(:id) }, class_name: 'AccountsUser'
  accepts_nested_attributes_for :owner
end

class AccountsUser
  belongs_to :account, inverse_of: :accounts_user
  belongs_to :user, autosave: true, inverse_of: :accounts_user
  accepts_nested_attributes_for :user
end

class User
  has_many :accounts, through: :accounts_users
  has_many :accounts_users, autosave: true, dependent: :destroy, inverse_of: :user
  accepts_nested_attributes_for :accounts_users, reject_if: :all_blank
end

# AccountsController#account_create_params
params.require(:account).permit(
  :plan_id,
  :name,
  :subdomain,
  {
    owner_attributes: {
      user_attributes: [
        :email,
        :first_name,
        :last_name
      ]
    }
  }
)

# rspec account_create_params
let(:valid_account_params) do
  {
    plan_id: plan.id,
    name: 'Name',
    subdomain: 'subdomain',
    owner_attributes: {
      user_attributes: [
        email: 'jane@doe.com',
        first_name: 'Jane',
        last_name: 'Doe'
      ]
    }
  }
end

@account = Account.new(account_create_params)
#> NoMethodError: undefined method `with_indifferent_access' for #<Array:0x000056472e0799c0>
from /usr/local/bundle/gems/activerecord-5.2.0.rc1/lib/active_record/nested_attributes.rb:412:in `assign_nested_attributes_for_one_to_one_association'

它必须抱怨user_attributes数组,并且看到它来自一个名为assign_nested_attributes_for_one_to_one_association的方法,Rails似乎错误地认为AccountsUsers和Users之间的关系是一对一的,不是一对多。

我已经三次检查了关联。你们有什么感想? Rails 5.2 bug也许?

1 个答案:

答案 0 :(得分:0)

这里有几个问题。我发现允许参数并提供它们需要不同的语法:

def account_create_params
  params.require(:account).permit(
    :plan_id,
    :name,
    :subdomain,
    {
      owner_attributes: {
        user_attributes: [
          :email,
          :first_name,
          :last_name,
          :password
        ]
      }
    }
  )
end

VS

let(:valid_account_params) do
  {
    plan_id: plan.id,
    name: 'Name',
    subdomain: 'subdomain',
    owner_attributes: {
      user_attributes: {
        email: email_valid,
        first_name: 'Jane',
        last_name: 'Doe',
        password: 'password'
      }
    }
  }
end

有点令人困惑,但它有效。 AccountsUser上的inverse_of错误。我需要复数:

belongs_to :account, inverse_of: :accounts_users, optional: true
belongs_to :user, autosave: true, inverse_of: :accounts_users

我还需要可选:true属于帐户,尽管accepted_nested_attributes_for正确设置关系。有一个鸡与蛋的情况,其中AccountUser无效,因为帐户不存在,并且帐户无法保存,因为AccountsUser无效。这可能是Rails 5&#39;功能&#39;。