Frank Weindel
Frank Weindel

Reputation: 1282

One Way One-To-One Association in CakePHP

I have an idea of how to do this but it doesn't seem like proper convention. I have a Submission model and a Revision model each with their similarly named tables. Each Submission can have one or more Revisions associated to it in a $hasMany relationship. The Revision model hence has a $belongsTo relationship linking back to the Submission.

In addition to having this relationship, the Submission model needs to have another association (called activeRevision) to a particular Revision in a $hasOne style of relationship. However, the $hasOne type requires the foreign key to be in the Revision table. I want it to be in the Submission table, so I don't need to query all of the Submission's Revisions to find the active one. I realized just specifying a $belongsTo relationship in the Submission would do what I want, but this feels wrong to me as now the two models "belong to eachother".

Is there a better way to go about this?

Upvotes: 0

Views: 893

Answers (1)

thaJeztah
thaJeztah

Reputation: 28987

I wouldn't worry too much because of the 'naming' of the relation. By having the foreign key of the Revision inside the Submission table, CakePHP is, in fact, right that you've created a 'belongsTo' relation.

Although not strictly the 'right' (?) relation, in this situation, this looks like it's an easy way to achieve what you want. Just be sure to add an additional condition to your relation to prevent that a revision of another submission can be set as the current revision, i.e.;

 public $belongsTo = array(
     'Revision' => array(
         'conditions' => array(
             'Revision.submission_id = Submission.id',
         )
      )
 );

However, make sure to add a proper comment in your code to prevent confusion if you're (or somebody else is) looking at your code in a later stage. (e.g. "note: using belongsTo relation, because its easier to maintain)

If you really want to convert it to a hasOne relation, you'll have to add an additional column to the 'Revisions' table, for example 'is_curreny_revision'. However, you will also need to be sure that only one revision of a submission can be set to be the current revision.

If you're using PostgreSQL, this can be achieved using a 'partial unique' index (see this question on StackOverflow; PostgreSQL: Conditional unique constraint). MySQL does not support partial indexes, so you're out of luck there

Upvotes: 1

Related Questions