Attachable Behavior

19 Jun
2009

It’s not normally a pain to add new HABTM relationships in CakePHP: just edit two the two model files, throw in some almost-stock code, and bob’s yer uncle. But I found myself in a sticky situation: I’m writing (almost done!) a general-purpose CMS, the core of which will be used by multiple sites. The ‘base’ of the CMS, such as the pages controller, the user auth system, and the media attachment system, are mostly contained within the core – only the view files are installed on a site-by-site basis. Since my Attachment model (the model that deals with attachments such as images, videos and documents to other models) is part of the core, I couldn’t just edit the HABTM array in the Attachment class every time I wanted to add a new association (since all relationships should be reciprocal). So, the solution I came up with is a behavior that just binds the HABTM associations on the fly, with the only configuration being the addition of Attachable to a model’s $actsAs array.

Is this the best way to do things? I’m not sure. But it’s a solution that works for me and the CMS I’m making, though it would be easy enough to modify the behavior to make it completely dynamic. If there are enough requests for such a version I’ll do one up and post it.

Download the Attachable Behavior (zip)

To use the Attachable behavior, simply add it to the $actsAs array for a model. For example:

class PressRelease extends AppModel {
 var $name = 'PressRelease';
 var $actsAs = array('Attachable');
}

SQL

The table you use as the join table should look something like this (the default table):

CREATE TABLE IF NOT EXISTS `attachments_models` (
 `id` int(11) NOT NULL auto_increment,
 `created` datetime default NULL,
 `modified` datetime default NULL,
 `attachment_id` int(11) NOT NULL,
 `foreign_id` int(11) NOT NULL,
 `model` varchar(75) NOT NULL,
 `rank` int(11) NOT NULL default '1',
 PRIMARY KEY  (`id`)
) ENGINE=InnoDB ;

And that’s it. You’ll have an on-the-fly and reciprocal HABTM relationship between PressRelease and whatever you define the attachment model as, by default Attachment. Speaking of which…

Configuration Options

There are a number of configuration options when attaching the Attachable behavior to a model, most of which are the same as the HABTM config options. A quick rundown:

  • attachmentClass – default ‘Attachment’: the class to which the Attachable models will be attaching.
  • joinTable – default ‘attachments_models’: the HABTM join table used to, well, join the tables.
  • attachmentTable – default ‘attachments’: the table with which attachmentClass is associated.
  • attachmentForeignKey – default ‘attachment_id’: the foreign key for attachmentClass in joinTable.
  • foreignKey – default ‘foreign_id’: the foreign key field for the Attachable model in joinTable.
  • modelField – default ‘model’: the field that stores the name of the Attachable model in joinTable.
  • And then the rest of the HABTM config options, with the except of condition, which is hard-coded in conjunction with modelField.

2 Responses to Attachable Behavior

Avatar

Jamie Nay » Attachable Behavior for Dynamic HABTM Relationships in CakePHP 1.2

June 19th, 2009 at 7:31 pm

[...] Attachable Behavior [...]

Avatar

matt

April 20th, 2010 at 12:37 pm

Haven’t tested it out yet, but this is what I was looking for. So does the behavior cover the need for setting the habtm relationship in the model, or just provide the functionality to save the appropriate data and such to the table (the model and foreign_id)? I’ll keep working along if I come up with any suggestions or anything I’ll let you know, but it looks great.

Comment Form

top