Hey folks, I’ve been running into a problem that’s had me scratching my head for a while. I have a form submitting information to a controller action that looks like this:
I’m assuming it has something to with the way I’m assigning values and automatically converting something to an array?.. but I’m not really sure, and don’t fully understand the magic at work here.
The Yii framework is smart: $model->save(); will check your database query criteria. It will first search if the record (say the id you provide) you are about to "insert" exists. If it does then it changes its query to update instead of insert.
When you go $model = new Tour; what you are doing is making an instance of the object Tour.
This means your variable in which the instance of the object is created ($model in this case) now gets access to all the methods and attributes within that object, allowing you to call, manipulate whatever the case may be - anything inside the class.
Seeing the word delete there if you’re trying to delete a record you would use $model->delete(); which when called, will take the the criteria you specified before hand (like say you went $model->findAll(criteria)) then it would delete everything you found. I’m not sure exactly what it is you were going for, but the save operation has a built in check to see if a record exists or not because if it doesn’t you have to insert, and if it does you have to update.
Here’s the rest of the code that came after what I put in my first post that takes care of the odd little $delete array, if anybody else is following this and wondering:
[quote name="http://www.yiiframework.com/doc/guide/database.ar said:"]As we can see, we use the same save() method to perform insertion and updating operations. If an AR instance is created using the new operator, calling save() would insert a new row into the database table; if the AR instance is the result of some find or findAll method call, calling save() would update the existing row in the table. In fact, we can use CActiveRecord::isNewRecord to tell if an AR instance is new or not.
[/quote]
You still have to define a new instance of the class it just means that if you use the find-> functions before saving then it implies you are updating. Here’s the way the logic works:
You create a new instance of the class:
So now all your methods can be called $classInstance->method();
And all your attributes can be set / manipulated by $classInstance->attribute;
By assumption, a new class (unless done otherwise in the __construct function) all attributes are empty, thus they need to be set.
This is what the reference is talking about - in the event you define a new instance and use say a form for user input and the isset format - then what happens is when you call the save function the framework acknowledges that you have a new record to put into the database.
However lets say you did findAll(criteria);
This effectively pulls all the information found from that action and stores it into the appropriate attributes of that class.
Then you can change any attribute in that class instance that you want, and when you call save() the framework understands that this time it’s an update action not an insert.
lets say we had a table called users: with username, password, email
I make a new instance of User
and I set via a form the username and password and email attributes - then save. This will insert into the users table.
But lets say I make a new instance of User
and I search for username="my name"
The result (if found) will auto set password="my password" and email="my email"
Then lets say I change email to email="my new email"
This time around save identifies it’s an update. Hope that clears it up for you
I don’t have 100% of an idea for you, however here’s the information about save() within the CActiveRecords
/**
* Saves the current record.
* The record is inserted as a row into the database table if it is manually
* created using the 'new' operator. If it is obtained using one of those
* 'find' methods, the record is considered not new and it will be used to
* update the corresponding row in the table. You may check this status via {@link isNewRecord}.
* Validation may be performed before saving the record. If the validation fails,
* the record will not be saved.
* If the record is being inserted and its primary key is null,
* after insertion the primary key will be populated with the value
* generated automatically by the database.
* @param boolean whether to perform validation before saving the record.
* If the validation fails, the record will not be saved to database.
* The validation will be performed under either 'insert' or 'update' scenario,
* depending on whether {@link isNewRecord} is true or false.
* @param array list of attributes that need to be saved. Defaults to null,
* meaning all attributes that are loaded from DB will be saved.
* @return boolean whether the saving succeeds
*/
public function save($runValidation=true,$attributes=null)
{
if(($scenario=$this->getScenario())==='')
$scenario=$this->getIsNewRecord()?'insert':'update';
if(!$runValidation || $this->validate($scenario,$attributes))
return $this->getIsNewRecord() ? $this->insert($attributes) : $this->update($attributes);
else
return false;
}
My suggestion to you is to override a beforeSave() and afterSave() and then put echo statements with the values you’re trying to save and such - see if everything is going according to plan before and after the save.
Gotcha Makes sense too, unless you’re plodding along like me assuming that Model::model()->find() does all the work for you. Now, I wonder why it took me two months to run into that problem…