Just don't 'get' "has one" and "belongs to one"

Well, I understand what they do and how, I just don’t get why!

It seems to me that any time you would have this relationship between
two tables…they should be one table! Agile Rails book gives what
seems to me to be a lame example for this. They use the example of an
“invoice” and an “order”. An invoice belongs to an order and an order
has one invoice. Seems to me that an invoice is a view, not a model.
An invoice is a way to show or print the relevant parts of an order.

Anyway, back to my dilemma. Can someone supply me with an example of a
situation where you would use this relationship where it wouldn’t be
better to just have all of the relevant columns in one table?

thanks much,
jp

On 16 Aug 2006, at 16:25, Jeff P. wrote:

of a
situation where you would use this relationship where it wouldn’t be
better to just have all of the relevant columns in one table?

How about modelling a husband/wife relationship with Person
has_one :spouse ?

Jeff P. wrote:

Well, I understand what they do and how, I just don’t get why!

Book belongs_to Author, Author has_many Books.

A.

I can imagine a situation where you have a need for additional
attributes/fields on an existing model/table (perhaps from a plugin,
engine or shared applicaton), but you do not want to modify the existing
table structure. In that instance, you could create a new model/table
with your additional fields, and link the two together with a
has_one/belongs_to_one relationship.

Alan F. wrote:

Jeff P. wrote:

Well, I understand what they do and how, I just don’t get why!

Book belongs_to Author, Author has_many Books.

A.

Sorry, you didn’t mean has_one and belongs_to separately, you meant
together :slight_smile:

Generally I try and think about objects, rather than tables, because I’m
a programmer, not a DBA. So separate concepts are separate models (like
Invoice and Order) and using rails means they get stored in separate
tables.

I focus on what makes sense at the Object level, not at the DB level.

A.

Here is an example from my current project. I’m using the ActiveRBAC
plugin
to manage logins. But, I want to store more information about the user
than
is contained in the User model that comes with ActiveRBAC. To do that,
I
set up a one_to_one relationship between the User and my Contact models.

Class Contact …
has_one :user

end

From the DBA perspective, you might want to separate sensitive data from
public data by spliting the table. Such as splitting sensitive personal
info from the Employee record. This allows ad-hoc queries against the
Employee table without having to written complex stored procedures to
protect the sensitive data based on user rights.

-Larry

Jonathan del Strother wrote:

Anyway, back to my dilemma. Can someone supply me with an example of a
situation where you would use this relationship where it wouldn’t be
better to just have all of the relevant columns in one table?

How about modelling a husband/wife relationship with Person has_one
:spouse ?
Surely you mean to model a :belongs_to relationship there :stuck_out_tongue_winking_eye:

(wonders if this will be the start of a flamewar about the removal of
‘obey’ from the wedding vows
)
Regards
Stef

Well, I understand what they do and how, I just don’t get why!

calm down…

It seems to me that any time you would have this relationship between

two tables…they should be one table!

not always. it all depends.

[…] Can someone supply me with an example of a

situation where you would use this relationship where it wouldn’t be
better to just have all of the relevant columns in one table?

Let’s see if I can explain (my english is pretty bad). I find it useless
when databases are in 3NF, but not when the DBA doesn’t know about
normalization. Even said this, we had to use it at my enterprise.

we manage some engineering projects here in the database, and we used to
have the following.

one budget request <-> one budget <-> one project.

why? because a budget request can easily be in the database about a
month
before generating a budget, and a budget can be in the database about
two or
three months before the project is accepted (and it’s created just after
accepted, not with the budget request). If we use null-by-default fields
in
the database, we perfectly can save the info and still maintain the 3NF
(in
a 800-table database it’s very hard!!!)

But, having some null fields in these tables require:

a) a trigger/stored procedure/function which stop us to write in the
registry if we don’t fill all the registries required for the project.
Disadvantage of this is that if you want to create a new field under the
“project” section of the table, you have to modify the entire code for
this
table. (I already have it done!)

b) separating these using the same primary key or at least a unique key
which is also the foreign key pointing to the table before. (in the
budget->project’s case, since a project has a serial number).

As we use a lot of programming languages for different purposes/targets,
I
decided to separate the tables… less coding, better understanding.
Projects go with Projects, Budgets with Budgets, and we don’t mix stuff
that
is related but not the same.

It breaks 3NF, but the database is still consistent with its data.

thanks much,

How about modelling a husband/wife relationship with Person
has_one :spouse ?

historical results… what if he had one spouse before? can have just
one
active spouse, but till 20 if he/she wants.

From the DBA perspective, you might want to separate sensitive data from
public data by spliting the table. Such as splitting sensitive personal
info from the Employee record. This allows ad-hoc queries against the
Employee table without having to written complex stored procedures to
protect the sensitive data based on user rights.

false. even in SQLite and MySQL 5, you have views. You can deny access
(by
REVOKE ALL ON table FROM user) to the entire sensitive data but write a
view
which shows exactly what the user needs, and apply filters to this view
(in
fact it’s a table composed from a select resultset).

adding/updating something to the tables when it is required can be done
by
rewriting the query, which is, IMHO, a better, more secure and better
maintainable solution. adding a new field doesn’t break the view, and
the
INSERT/UPDATE query, if well rewritten, won’t be any sacrifice.

Financial example (double bookeeping):

debit has_one credit

This allows you to treat debits and credits separately.

You are right that has_one (1:1) relationships can always bve modeled
as a single table. Reasons for using 1:1 relationships include:

performance
semantic meaning (in the spouse example given berfore- does your
domain deal with Persons or MarriedCouples?)
less complex queries

On the last one, consider the debit.credit example above. If I want to
work with all credits an account has received, I can simply do (given
appropriate has_many and belongs_to set up between account and
credits):

account.credits.each {|credit| … do stuff …}

If they were put together in a single model class (say
financial_transaction), I would always have to write conditional code:

account.financial_transactions.each do |trans|
next if trans.creditor != acount
… do stuff with trans …
end

Much more verbose, and the meaning of a financial_transaction’s fields
changes depending from which account you are looking at the
transaction.

Cheers,
Max

Max M. wrote:

Financial example (double bookeeping):

debit has_one credit

This allows you to treat debits and credits separately.

You are right that has_one (1:1) relationships can always bve modeled
as a single table. Reasons for using 1:1 relationships include:

performance
semantic meaning (in the spouse example given berfore- does your
domain deal with Persons or MarriedCouples?)
less complex queries

On the last one, consider the debit.credit example above. If I want to
work with all credits an account has received, I can simply do (given
appropriate has_many and belongs_to set up between account and
credits):

account.credits.each {|credit| … do stuff …}

If they were put together in a single model class (say
financial_transaction), I would always have to write conditional code:

account.financial_transactions.each do |trans|
next if trans.creditor != acount
… do stuff with trans …
end

Much more verbose, and the meaning of a financial_transaction’s fields
changes depending from which account you are looking at the
transaction.

Cheers,
Max

Thanks guys…you both confirmed my understanding of what it was doing
and gave me some good examples of why you might want to do it anyway.
:slight_smile:

thanks,
jp

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs