开发者

Confusion over the tables for has_one and has_many

In the Rails ActiveRecord Associations guide, I'm confused over why the tables for has_one and has_many are identical:

Example tables for has_many:

customers(id,name)
orders(id,customer_id,order_date)

Example tables for has_one: these tables will, at the database level, also allow a supplier to have many accounts, but we just want one account per supplier

suppliers(id,name)
accounts(id,supplier_id,account_number) #Foreign Key to supplie开发者_开发百科r here??

Shouldn't the tables for has_one be like this instead:

suppliers(id,name,account_id) #Foreign Key to account here
accounts(id,account_number)

Now because the account_id is in the suppliers table, a supplier can never have more than one account.

Is the example in the Rails Guide incorrect?

Or, does Rails use the has_many kind of approach but restricts the many part from happening?


If you think about this way -- they are all the same:

1 customer can have many orders, so each order record points back to customer.

1 supplier can have one account, and it is a special case of "has many", so it equally works with account pointing back to supplier.

and it is the same case with many-to-many, with junction table pointing back to the individual records... (if a student can take many classes, and one class can have many students, then the enrollment table points back to the student and class records).

as to why account points back to supplier vs account points to supplier, that one I am not entirely sure whether we can have it either way, or one form is better than the other.


I believe it has to do with the constraints. With has_one rails will try to enforce that there is only one account per supplier. However, with a has_many, there will be no constraint enforced, so a supplier with has_many would be allowed to exist with multiple accounts.

It does take some getting used to when thinking about the relationships and their creation in rails. If you want to enforce foreign keys on the database side (since rails doesn't do this outside of the application layer), take a look at Mathew Higgins' foreigner


If I understand your question correctly, you believe there is a 1:1 relationship bi-directionally in a has_one/belongs_to relationship. That's not exactly true. You could have:

Class Account
  belongs_to :supplier
  belongs_to :wholesaler
  belongs_to :shipper
  # ...
end

account = supplier.account       # Get supplier's account
wholesaler = Wholesaler.new
wholesaler.accounts << account   # Tell wholesaler this is one of their suppliers
wholesaler.save

I'm not saying your app actually behaves this way, but you can see how a table -- no, let's say a model -- that "belongs to" another model is not precluded from belonging to any number of models. Right? So the relationship is really infinity:1.

I should add that has_one is really a degenerate case of has_many and just adds syntactic sugar of singularizing the association and a few other nits. Otherwise, it's pretty much the same thing and it's pretty much why they look alike.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜