【问题标题】:Has_One through a model when the model has_manyhas_One 通过一个模型当模型 has_many
【发布时间】:2013-05-23 19:47:29
【问题描述】:

我正在尝试设置一个系统,让我的帐单配置文件可以通过用户保存地址和付款方式。使用地址,它工作正常,因为用户只有一个,但使用付款方式,因为用户 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?**

帐单资料

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

用户

class User < ActiveRecord::Base
  ...

  has_one :billing_profile

  has_many :payment_methods

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

地址

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

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

支付方式

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

  belongs_to :user

  validates_presence_of :user_id
end

BillingProfile 表格

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

知道这是否可能,或者是否有更好的方法来解决它?当我创建计费配置文件时,我曾尝试过仅手动设置 id 的想法,但随后我必须创建方法来获取付款方式,这并不可怕,但如果 R​​ails 能够做到这一点,那就太好了我。

编辑

既然看来我所希望的似乎是不可能的。我简单地向 Billing Profile 添加了一个方法来模拟关联。

def payment_method
    PaymentMethod.find(payment_method_id)
  end 

【问题讨论】:

  • 您需要使用has_one :payment_method。为了保持一致性(付款方式应该与用户相同),您可以使用自定义验证方法。
  • 这不会真正起作用,因为当您对其运行查询时,它会在 PaymentMethods 表中查找不存在的 billing_profile_id。我想在不添加该列的情况下建立关联

标签: ruby-on-rails ruby-on-rails-3 associations relationship


【解决方案1】:

:through 选项用于链接关系。因此,以下情况成立:

billing_profile.user.address == biling_profile.address

但是,以下内容不可能为真(因为您只希望一侧有一个列表,而另一侧则需要一个列表):

billing_profile.user.payment_methods == billing_profile.payment_method

您需要一个额外的列来建立这种关系。如果两者返回相同,则只能使用 :through 关系,因为没有“额外内存”来仅保存列表中的一个。

因此,简而言之,您需要添加 has_onebelong_to 而不添加 :trhough,并添加一个新列(额外内存)来保持这种关系。

【讨论】:

  • 如果还不清楚,请问我,我可以尝试多写一点,但目前找不到更好的解释方式。
  • 唉,这就是我所担心的。我希望有一些隐藏的铁轨魔法:P
  • @justNeph 抱歉,今天没空 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
相关资源
最近更新 更多