Given the below schemas and their models I have been contemplating the best way to link field(s) of one model to another.
User Schema
- id (primary key)
- name
- status
BlogEntry Schema
- id (primary key)
- user_id (foreign key => user => id )
- title
- entry
- status
BlogComment Schema
- id (primary key)
- blog_entry_id (foreign key => blog_entry => id )
- user_id (foreign key => user => id )
- message
- status
User Model
PHP Code:
class User {
public static $fields = array('id','name','status');
public static $hasMany = array('blog_entries','blog_comments');
}
BlogEntry Model
PHP Code:
class BlogEntry {
public static $fields = array('id','user_id','title','entry','status');
public static $foreignKeys = array(
'user_id'=>'User'
);
}
BlogComment Model
PHP Code:
class BlogComment {
public static $fields = array('id','user_id','title','entry','status');
public static $foreignKeys = array(
'user_id'=>'User'
,'blog_entry_id'=>'BlogEntry'
);
}
This would be used so that if the status of the user where to changed then that change would cascade all dependencies on the linked column.
PHP Code:
$user = new User(1); // locate user with primary key of 1
$user->status = 0; // set the status to 0
$user->update(); // update user and cascade the changed value(s) to dependencies
The SQL that would be built from this procedure would be similar to the below.
Code SQL:
UPDATE users SET STATUS = 0 WHERE id = 1
Code SQL:
UPDATE blog_entries SET STATUS = 0 WHERE user_id = 1
Code SQL:
UPDATE blog_comments SET STATUS = 0 WHERE blog_entry_id IN (SELECT DISTINCT id FROM blog_entries WHERE user_id = 1)
Code SQL:
UPDATE blog_comments SET STATUS = 0 WHERE user_id = 1
The result would be that all dependencies that shared a link with the changed property would be updated also.
The model property I was considering using to declare links would be links.
Thus, the previously discussed models would now be defined as below with the added links property.
User Model (revised)
PHP Code:
class User {
public static $fields = array('id','name','status');
public static $hasMany = array('blog_entries','blog_comments');
}
BlogEntry Model (revised)
PHP Code:
class BlogEntry {
public static $fields = array('id','user_id','title','entry','status');
public static $foreignKeys = array(
'user_id'=>'User'
);
public static $links = array(
'User'=>array(
'status'=>'status'
)
);
}
BlogComment Model (revised)
PHP Code:
class BlogComment {
public static $fields = array('id','user_id','title','entry','status');
public static $foreignKeys = array(
'user_id'=>'User'
,'blog_entry_id'=>'BlogEntry'
);
public static $links = array(
'BlogEntry'=>array(
'status'=>'status'
)
,'User'=>array(
'status'=>'status'
)
);
}
In the simplest of forms this seems to be the direction I'm heading.
However, I'm unsure if I'm forgeting anything vitally important here. I think all I need to make this work would be to know that one models field can be directly linked to another.
Using this approach I think it would also be possible to create unions between models. I haven't got this far yet but it seems like a definate possible which I haven't seen yet in other ORM libraries.
- User(status) => BlogComment(status)
- User(status) => BlogEntry(status)
- BlogEntry(status) => BlogComment(status)
Seems like that is all that would be needed to create a union. Although, then perhaps there would need to be some way to drop links. For instance if links were only declared for the purpose of creating a join.
User Model (revised)
PHP Code:
class User {
public static $fields = array('id','name','status');
public static $hasMany = array('blog_entries','blog_comments');
}
BlogEntry Model (revised)
PHP Code:
class BlogEntry {
public static $fields = array('id','user_id','title','entry','status');
public static $foreignKeys = array(
'user_id'=>'User'
);
public static $links = array(
'User'=>array(
'status'=>'status'
,'id'=>'id'
)
);
}
BlogComment Model (revised)
PHP Code:
class BlogComment {
public static $fields = array('id','user_id','title','entry','status');
public static $foreignKeys = array(
'user_id'=>'User'
,'blog_entry_id'=>'BlogEntry'
);
public static $links = array(
'BlogEntry'=>array(
'status'=>'status'
,'id'=>'id'
)
,'User'=>array(
'status'=>'status'
,'id'=>'id'
)
);
}
In the above scenario one wouldn't want to cascade the id so perhaps the update() method could take a argument list of valid links to cascade.
PHP Code:
$user = new User(1); // locate user with primary key of 1
$user->status = 0; // set the status to 0
$user->update(array('status')); // only cascading on status
Any thoughts, recommendations,insights or overlooks in the creation of this functionality appreciated.
Have you seen anything like this before in a ORM and do you think its a feature worth integrating?
I'm not even sure of a good name for this module/functionality as I've never seen something like it before. However,I think it has relevance and furthers the idea of managing a collection of related data through a simple interface which is the dominant purpose what I'm building.
thanks
Bookmarks