【问题标题】:multiple belongs_to on model causing errors with accepts_nested_attributes_for on parent模型上的多个 belongs_to 导致父级上的 accept_nested_attributes_for 错误
【发布时间】:2015-02-24 14:55:15
【问题描述】:

我有一个子模型belongs_to 有两个潜在的父模型。其中之一是我尝试将accepts_nested_attributes_forsimple_form 一起使用。这样做会给我这个错误: You tried to define an association named transaction on the model Exchange, but this will conflict with a method transaction already defined by Active Record. Please choose a different association name.

这是我的代码:

交换模型

class Exchange < ActiveRecord::Base
  has_one :transaction
  accepts_nested_attributes_for :transaction
end

类别模型

class Category < ActiveRecord::Base
  has_many :transactions
  monetize :budgeted_cents
end

交易模型

class Transaction < ActiveRecord::Base
  belongs_to :category, :class_name => 'Category', :primary_key => 'category_id'
  belongs_to :exchange, :class_name => 'Exchange', :primary_key => 'exchange_id'
  validates :note, presence: true
  monetize :amount_cents, with_model_currency: :in_cents_currency

  def self.all_currencies(hash)
    hash.keys
  end
end

我在这里做错了什么还是我从错误的角度解决问题?

谢谢

【问题讨论】:

  • 如消息所述,您需要将关联名称更改为 transaction 以外的名称。
  • 但是,关联的名称 (transaction) 不是指的是它与 to 关联的模型的名称吗? (即它必须命名为transaction)@vee
  • 是的,但是transaction 是一个已经在 ActiveRecord 中定义的方法,它是一种保留字。您可以在 Exchange 模型中执行 has_one :tx, class_name: 'Transaction' 然后 accepts_nested_attributes_for :tx
  • 更多关于 AR transaction 方法:api.rubyonrails.org/classes/ActiveRecord/Transactions/…
  • 我进行了更改,但现在在我的控制器中,当我执行@exchange.tx = Transaction.new 之类的操作时出现错误can't write unknown attribute 'exchange_id'。这是否也与transaction 有点保留有关?顺便感谢您的帮助!

标签: ruby-on-rails ruby activerecord simple-form


【解决方案1】:

正如@vee 所指出的,'transaction' 是一个保留字,尽管直到 Rails 4.1.x 版本才强制执行。

在整个应用程序范围内更改“交易”一词需要在客户预算之外很好地工作。所以我使用的解决方案是将模块“ActiveRecord::Associations::Builder”替换为此处的副本(针对您的 Rails 版本进行调整):

https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/associations/builder/association.rb

我在我的应用 (lib/active_record/associations/builder) 的层次结构中的同一位置放置了该 association.rb 代码的副本,除了以下行被注释掉:

# if model.dangerous_attribute_method?(name)
# raise ArgumentError, "You tried to define an association named #{name} on the model #{model.name}, but " \
# "this will conflict with a method #{name} already defined by Active Record. " \
# "Please choose a different association name."
# end

您可以尝试仅在“name”与冲突的“transaction”匹配时才跳过此(修改“if”)。 对于其他任何被卡住的人,这条路线可以避免必须保持在 Rails 版本 4.0.x 或早期的 4.1 测试版。

【讨论】:

  • 我不得不对此投反对票,因为不应该鼓励这种黑客行为。这不是问题的解决方案,而是为神秘的错误铺平道路。正确的解决方案是搜索并替换关联并将其重命名为其他名称,例如belongs_to :my_transaction, class_name: 'Transaction'.
  • 我会让我的客户把账单寄给你 :) - 它在整个应用程序代码中都被引用(在我继承项目之前)。不应该在主要版本中破坏有效的代码。至少,“破坏者”可以提供一个 gem 来恢复以前的工作功能。同样,此代码修复只是找到了导致损坏的新源。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多