简体   繁体   English

当模型has_many时,Has_One通过模型

[英]Has_One through a model when the model has_many

I'm trying to set up a system where my Billing Profile can hold an Address and Payment Method through a User. 我正在尝试设置一个系统,我的结算资料可以通过用户持有地址和付款方式。 With addresses, it works fine since User only has one but with Payment Method, since User has_many, I keep getting the error: 使用地址,它工作正常,因为用户只有一个但使用付款方式,因为用户has_many,我不断得到错误:

ActiveRecord::HasManyThroughSourceAssociationNotFoundError: 
Could not find the source association(s) :payment_method_id in model User. 
Try 'has_many :payment_method, :through => :user, :source => <name>'. 
Is it one of :address, :billing_profile, or :payment_methods?**

BillingProfile BillingProfile

class BillingProfile < ActiveRecord::Base
  attr_accessible :user, :payment_method
  belongs_to :user
  has_one :address, :through => :user
  has_one :payment_method, :through => :user
end

User 用户

class User < ActiveRecord::Base
  ...

  has_one :billing_profile

  has_many :payment_methods

  has_one :address, :as => :addressable
  accepts_nested_attributes_for :address
end

Address 地址

class Address < ActiveRecord::Base
  belongs_to :addressable, :polymorphic => true

  attr_accessible :city, :country, :state, :street_line_1, :street_line_2, :zip_code
end

PaymentMethod 付款方法

class PaymentMethod < ActiveRecord::Base
  attr_accessible :user_id, :is_default

  belongs_to :user

  validates_presence_of :user_id
end

BillingProfile Table BillingProfile表

create_table :billing_profiles do |t|
  t.integer :user_id
  t.integer :payment_method_id
  t.timestamps
 end

Any idea how if this is even possible or if there is a better way to approach it? 知道如果这是可能的,或者是否有更好的方法来接近它? I have dabbled in the idea of just manually setting the id's when I create the Billing Profile but then I'd have to create methods to get the payment method which is not terrible but it'd be nice if Rails was able to do it for me. 我在创建账单配置文件时只涉及手动设置id的想法,但后来我必须创建方法来获取付款方法并不可怕但是如果Rails能够做到这一点就很好我。

EDIT 编辑

So since it appears that what I hoped for is not possible. 所以,因为看起来我希望的是不可能的。 I simple added a method to Billing Profile to simulate the association. 我简单地向Billing Profile添加了一个方法来模拟关联。

def payment_method
    PaymentMethod.find(payment_method_id)
  end 

The :through option is there to link relationships. :through选项用于链接关系。 So, the following hold true: 所以,以下是正确的:

billing_profile.user.address == biling_profile.address

However, the following can't be true (because you want only one in one side and a list in the other): 但是,以下情况不可能成立(因为您只需要一方在一方而另一方只有一个列表):

billing_profile.user.payment_methods == billing_profile.payment_method

You need an extra column to make this relationship. 您需要一个额外的列来建立这种关系。 You can only use the :through relationship if both returns the same, because there is no "extra memory" to hold only one from a list. 如果两者都返回相同,则只能使用:through关系,因为没有“额外内存”只能从列表中保存一个。

So, in short, you need to add a has_one or a belong_to without :trhough and add a new column (extra memory) to hold this relationship. 因此,简而言之,您需要添加has_onebelong_to而不使用:trhough belong_to并添加新列(额外内存)以保持此关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM