[Dbix-class] has_a mutator: set_rel_single
davekam at pobox.com
Fri Jul 29 18:58:09 CEST 2005
There are a number of possibilities for how we want this mutator to
behave. First of all, it's important to correctly conceptualize the
has_a relationship (and separate it from might_have, must_have, is_a,
or whatever else). Basically, it is the mirror image of a has_many
relationship. The has_many direction is easier to cnceptualize -- you
have an accessor for retrieving the list of related rows, and a
mutator for adding a new row. The has_a direction is more subtle.
From the point of view of _all_ rows that participate it's a many-to-
one relationship, but from the point of view of a single row, it's
essentially one-to-one. However, it's a peculiar kind of one-to-one.
For example, many species may belong to one genus. On the other hand,
a specific species might turn out to be a member of any of the known
genera, or even of a new one, but it doesn't make sense to say that
it actually belongs to more than one. The currently known genera just
represent a potential set among which the species may belong to one.
It may be desirable to reclassify it many times in the future, but at
any given moment it can only be considered belonging to one (leaving
out the possibility of "unknown" or "unresolved").
I would like to propose that there are at least three distinct usage
cases for a has_a mutator. I will use species and genus to refer to
the columns in the respective tables, so it's clear which direction
the relationship is going.
(1) The user would like to assign the species to a new genus. This
involves inserting a row into the genus table, possibly with relevant
data to fill in the rows, and storing the key in the species table.
(2) The user would like to reassign the species to a different genus.
This involves changing the key in the species row to refer to a
different genus row.
(3) The user would like to modify something in the genus row.
The last case is the easiest to handle -- it can be done by simply
calling the get_rel_single() accessor, then calling the necessary
column mutators on the returned object. The first two are trickier.
The logical way to distinguish them is to allow a hash of column
names and values to be passed and recognize (2) by the fact that a
primary key was present (it could be more than one column). Any other
columns present in the hash could either be ignored or cause an
error. (I think it would be very confusing if they were used to
update the genus row indicated by the primary key!) Case (1) could be
assumed if no primary key was present. Or it could require a "create"
or "force" attribute of some sort, and the mutator would simply give
an error if it had no primary keys and no create/force attribute.
Does this seem like a reasonable overview of the problem domain?
More information about the Dbix-class