The EAdvancedArBehavior extension takes away some of the complexities involved when saving objects, for example, with MANY_MANY and BELONGS_TO relations.
Built on Yii 1.1.6
The EAdvancedArBehavior extension adds up some functionality to the default possibilites of yii´s ActiveRecord implementation.
To use this extension, just copy this file to your extensions/ directory, add 'import' => 'application.extensions.EAdvancedArBehavior', [...] to your config/main.php and add this behavior to each model you would like to inherit the new possibilities:
public function behaviors(){
return array( 'EAdvancedArBehavior' => array(
'class' => 'application.extensions.EAdvancedArBehavior'));
}
Depending on the functionallities you want to enable, you need to set some configuration parameters. This is described below.
Suppose you have a User and Project model having a MANY_MANY relation, for example:
User.php:
public function relations() {
return array( .....
'projects' => array(self::MANY_MANY, 'Project', 'tbl_project_user(user_id, project_id)') );
}
Project.php:
public function relations() {
return array( .....
'users' => array(self::MANY_MANY, 'User', 'tbl_project_user(project_id, user_id)') );
}
Now you can use it like
$user = User::model()->findBPk(12) ; $projects = Project::model()->findAll( $criteria ) ; $user->projects = $projects ; $user->save() ;
Remove relations like
$user->projects = array() ; // cleans up the relation table // or $user->delete() ;
With this extension you can connect two related objects as follows:
$user = new User(); $user->company = Company::model()->find($conditions, $params); $post->save();
Without this extension, you would have to do this as follows:
$user = new User(); $company = Company::model()->find($conditions, $params) ; $user->company_id = $company->id ; $post->save();
Suppose a User HAS_ONE Address and HAS_MANY Emails, and Address/Email BELONGS_TO User (both have the foreignkey column user_id). So you can do now:
$user = new User() ; $user->emails = array( $email1, $email2, ... ) ; $user->address = $address ; $user->save() ;
See: http://code.google.com/p/yiiext/downloads/detail?name=ensureNull_1.0.1.zip
Use it like
return array(
'EAdvancedArBehavior' => array(
'class' => 'application.extensions.EAdvancedArBehavior',
'useOnUpdate' => false, // set empty fields to NULL only on inserts not updates
));
Although the title of this section suggests something which cannot be done with MySQL, there is a nice workaround available. This extension provides the means to have a table with one column for the insert time and an other for the last modification time. First, add the following two columns to your table definition
update_time timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, created_time timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
Next, configure the following parameters
return array(
'EAdvancedArBehavior' => array(
'class' => 'application.extensions.EAdvancedArBehavior',
'useNullOnTimestamp' => TRUE, // set timestamps with a default value of 0000-00-00 00:00 to NULL (for inserts)
'useOnUpdate' => true, // required
'onUpdateTimestamp'=>'update_time', // column name of the update time
),
);
To reduce unnecessary database queries, define the relations which are modified before save():
$model->ignoreRelationsExcept( array('company', 'address') ) ;
$model->save() ;
All relations are ignored except company and address
add more functionalities (any AR suggestions are welcome!)
Total 14 comments
I have got error when running my application on php 5.4.4 buildin server
Any idea how to fix this?
I use EAdvancedArBehavior 2.3
Update: Replace beforeSave function definition
Solution found here...
The class you build is awesome by the way. But it's always referenced as "EAdvancedArBehavior". While the class name in the file is spelled with a lower b in "behavior". This is a problem in Unix environments as the filename does have a capital B in it. The problem doesn't occur unless you are using the class as a behavior for an object that needs to (serialized and) unserialized, which leads to an autoload error.
To avoid error with alphanumeric keys, line 217 should be:
Hi, I have noticed that this extension only work when creating an object that has a 'HAS_ONE' relation, but not also when updating.
I want to do something like this: $client->attributes=$_POST['Client']; $client->clientSetup->attributes = $_POST['ClientSetup']; $client->save();
The problem is on line 67 of your code, because you only save if the foreignkey field is empty or different.
Could you fix this ?
thanks for pointing that out!!
I've uploaded a new version (v0.8) which solves this issue for HAS_ONE and HAS_MANY
Or did you experience it with MANY_MANY ?
cheers
Note: Do not use this extension on all your active records because on update it will update all items. I wanted to update one of my table element
post.view count. it updated all my tables.Hello
I've uploaded a new version which implements both suggested behaviors concerning deleting relations from the relation table.
Furthermore, the suggested 'transaction' behavior, I actually like how Yii does it (its easy to use) so I can't think of a better way to implement this!
Thanks a lot for the help!
Cheers
I think this will be also good feather to this extension. delete all relation if array will be empty. Ex:
enchantment of class function.
this extention better then save-relations-ar-behavior component, for me.
Hi again.
I introduced a new behavior:
very interesting, that would be useful! I have to perform a little bit of research first, but if I have figured something out I'll post my ideas here!
thnx for tip
Thank you for your attention.
Perhaps you might want to now implement the transaction.
thanks! I have it implemented in the current version (v0.3)
I suggest changing line 108 from: $this->owner->$relation[2] = $this->owner->{$key}->id;
To: $this->owner->$relation[2] = $this->owner->{$key}->primaryKey;
Leave a comment
Please login to leave your comment.