Example screenshot http://guides.rubyonrails.org/images/has_one_through.png
为什么他们使用has_one:通过这里。我们只能用has_one做同样的事情。什么是创建一个新课程的需要。你能给我一些好的例子吗?
以下是原始示例的链接 from Rails guide
修改
我们可以通过这种方式做同样的事情,使它成为一个has_one:通过
class Supplier < ActiveRecord::Base
has_one :account
end
class Account < ActiveRecord::Base
belongs_to :supplier // add a another column credit_rating in accounts table
end
答案 0 :(得分:2)
正在使用has_one :through
关联,因为联接模型(AccountHistory
)包含与Supplier
和Account
之间的关联相关的其他信息,即信用评级。
Rails指南中的这个示例选择得很差,因为使用has_one :through
比使用has_one
credit_rating
属性Account
更好的原因并不明显模型。
当您需要连接模型上的额外属性时,您应该使用has_one :through
或has_many :through
关联,这些属性在逻辑上不属于构成关联的其他模型。一个典型的例子是将图书借给图书馆内的用户。图书借阅的日期和持续时间属于(贷款)连接模型,因为从逻辑上讲,它们不是属于用户或图书的属性。在这种情况下,使用has_many :through
关联是合适的。
答案 1 :(得分:1)
因为使用has_one :through
,您可以向Account
答案 2 :(得分:1)
在某些情况下,您可能不希望向表中添加特定字段。在您的示例中,您实际上只需要一个表,因为您可以将account_number
和credit_ranking
添加到suppliers
表中。但有时将数据存储在多个表中是个好主意。然后你必须使用has_one
(一对一)关系。
在您的示例中,您还可以将属性supplier_id
添加到account_histories
,并将has_one :account_history, :through account
替换为has_one :account_history
,但这将是多余的,并且会使您的代码复杂化需要确保你不改变一个属性而忘记更新另一个属性。
<强>更新强>
如果您未将supplier_id
属性添加到account_histories
,则Rails将无法确定该表中的哪一行属于哪个供应商。找到它的唯一方法是查看相关的accounts
表。没有accounts
,您无法确定哪个account_history
属于供应商,因为accounts_histories
表没有suppliers
表的任何外键。
要获得没有account_history
选项的供应商的:through
,您必须执行此操作:
Supplier.find(id).account.account_history
:through
允许您将其替换为:
Supplier.find(id).account_history
正如您在更新中所写的那样,您可以将credit_ranking
属性添加到accounts
并且只有两个表。这将更加简单,但您可能不希望将该属性存储在同一个表中(因为您可能已经拥有许多其他属性,并且不想添加更多属性)。
答案 3 :(得分:1)
我认为在这种情况下,它取决于您如何设计数据库模型。 Rails的优点是,如果你使用一些遗留数据库,它可以处理几乎所有的关系类型。在这种情况下,您将使用:has_one:through,因为您的数据库表是以这种方式建模的。
建议使用三种模型的优点:帐户和AccountHistory之间存在清晰的分离。虽然您可以将Account和AccountHistory建模为一个组合模型,但是没有必要。 在这么小的例子中,这似乎没有用,但是例如: