通过未保存的子关联访问父级(has_many)

我有一笔与每笔付款相关的交易付款。 交易可以与付款,存款等相关联,因此我需要:通过关系。

付款类:

class Payment  :payment_transactions end 

和Transaction类:

 class Transaction  :transaction has_one :payment, :through => :payment_transaction end 

最后是PaymentTransaction类:

 class PaymentTransaction < ActiveRecord::Base belongs_to :payment belongs_to :transaction end 

将交易添加到付款时,我希望能够从新创建的交易中访问父信息(付款属性):

 2.1.0 :001 > p = Payment.new => # 2.1.0 :002 > p.save => true 2.1.0 :003 > p.transactions.build() => # 2.1.0 :004 > p.transactions.first.payment => nil 

我正在寻找一种方法来从与支付相关的新创建的交易中获取付款 – 但没有运气。 付款已保存,但事务仍未提交到数据库。 只有在保存付款并存储关联的交易时,我才能访问父对象:

 2.1.0 :005 > p.save 2.1.0 :008 > p.reload 2.1.0 :009 > p.transactions.first.payment => # 

使用:inverse_of是不可能的:通过关联。 🙁


编辑1:

试图通过代理关联访问父级:

应用程序/忧虑/ transaction_proxy.rb

 module TransactionProxy private def my_owner proxy_association.owner end end 

付款方式:

 has_many :payment_transactions has_many :transactions, -> { extending TransactionProxy }, :through => :payment_transactions 

加载付款:

 2.1.0 :006 > p = Payment.first Payment Load (0.2ms) SELECT "payments".* FROM "payments" ORDER BY "payments"."id" ASC LIMIT 1 => # 

设置交易:

 2.1.0 :007 > p.transactions.build() => # 

查询交易:

 2.1.0 :005 > p.transactions.first => # 2.1.0 :007 > p.transactions.first.payment => nil 

并尝试使用代理:

 2.1.0 :006 > p.transactions.first.my_owner NoMethodError: undefined method `my_owner' for # 

我假设交易中的.my_owner应该返回该交易的所有者(付款)?

你的代码看起来让我很困惑!


多态

我认为你会从交易模型的多态关联中受益。 这将允许您的交易属于paymentsdeposits或任何型号

您对through关系的使用意味着transactions只能与payments相关联,交易和付款对象必须先创建才能关联它们:

 class Transaction < ActiveRecord::Base belongs_to :transactable, polymorphic: true end class Payment < ActiveRecord::Base has_many :transactions, as: :transactable end class Deposit < ActiveRecord::Base has_many :transactions, as: :transactable end class Reward < ActiveRecord::Base has_many :transactions, as: :transactable end 

多态性协会


Extrabutes

如果你想保持你的has_many :through关联,你可以使用ActiveRecord Association Extensions proxy_association对象来检索你需要的数据

我们创建了一个脚本以获得额外的连接表数据,您将能够适应拉动子对象属性:

 #app/models/concerns/image_caption.rb module ImageCaption #Load def load captions.each do |caption| proxy_association.target << caption end end #Private private #Captions def captions return_array = [] through_collection.each_with_index do |through,i| associate = through.send(reflection_name) associate.assign_attributes({caption: items[i]}) return_array.concat Array.new(1).fill( associate ) end return_array end ####################### # Variables # ####################### #Association def reflection_name proxy_association.source_reflection.name end #Foreign Key def through_source_key proxy_association.reflection.source_reflection.foreign_key end #Primary Key def through_primary_key proxy_association.reflection.through_reflection.active_record_primary_key end #Through Name def through_name proxy_association.reflection.through_reflection.name end #Through def through_collection proxy_association.owner.send through_name end #Captions def items through_collection.map(&:caption) end #Target def target_collection #load_target proxy_association.target end end #app/models/message.rb has_many :image_messages has_many :images, through: :image_messages, extend: ImageCaption 

如果您希望我为您修改此代码,请在评论中提问!