Normally in CakePHP, when you add a record with a form to a database table, CakePHP will automatically fill in the "created" field in de database with the current date & time. It works for my table called "attractions" (model "Attraction").
But now, strange things are happening. When I add a record for:
model "AttractionProperty", table "attraction_properties"
model "AttractionTypes", table "attraction_types"
model "AttractionPropertyLink", table "attraction_properties_links"
...
... both the fields "created" and "modified" are filled in. I checked if the id of my model is set in the add action ($this->request->id), but it says "false". Is this a common problem or what could be the reason of this behavior?
Do you have modified field in your Attraction model as well?
It is a feature to always set the created and modified field, if present. If you want to prevent it, add 'modified' => false into your $data array, that you pass to Model::create($data) or Model::save($data).
Read more here
Related
I have two models, donors hasMany donations.
Upon creation of donor record, I want to update some donor fields. I tried using saveAssociated() as follows
$this->Donation->create();
$this->request->data['Donation']['donor_id'] = $id;
$this->request->data['Donor']['last_donated'] = date('Ymd H:i:s', strtotime('now'));
if($this->Donation->saveAssociated($this->request->data , array('deep' => true))){
}
Everything works except that the donor is not updated but a new donor record is created altogether.
Do I need to set the donor id manually somehow?
"Do I need to set the donor id manually somehow ?"
Yes.
More explanation:
In cake, if you want to update something, you need to pass the id, otherwise you'll create a new record. You can also "load" the model instance like
$this->Model->id = $id;
and then the save will update the row with that id. But I always find it more mentally-safe to add the id to the saved array, specially when using saveAll, saveMany and saveAssociated.
In your case, you must have the donor's id somewhere, cake is not that magical and it won't know what donor you are refering to.
Something like this
$this->request->data['Donor']['id'] = $the_id;
will do the trick.
... or you can save the donor's last_donated time with a different query, if it's giving you too much trouble.
I use three fields in Sqlserver Datavbase tables, for prevent delete records permanently by user:
IsDelete (bit)
DeletedDate (DateTime)
DeletedUserID (bigint)
I wish to set third field (DeletedUserID) by UI by some thing like this:
this.ExamdbDataSet.AcceptChanges();
DataRowView row = (DataRowView)this.BindingSource.Current;
row.BeginEdit();
row["DeletedUserID"] = User.User.Current.ID;
row.EndEdit();
this.ExamdbDataSet.AcceptChanges();
row.Delete();
and other two fields ,'IsDeleted' field and 'DeletedDate' are set automatically in table's 'After Delete Trigger'.
then commit changes to database with desire command successfuly with this code:
this.TableAdapterManager.UpdateAll(this.ExamdbDataSet);
but problem is , the 'DeletedUserID' is null in database.
and Question is : How to set 'DeletedUserID' field value by true way in UI?
I don't think it is a good way to do that. You have sliced a simple logic to separate parts, each being done in a different part of the application (UI, Trigger, ...). You set value of some field, and then DELETE the whole record! Don't expect anything else that the current situation.
You would better set all fields in UI (i.e. no trigger in this case), and change the query that loads data. For example,
Select * from table1 where IsDeleted=0
You didn't tell us anything about whether your use ASP.Net or WinForms. Give us more info.
Is there a way to write a CakePHP query to return all fields (columns) except one via find()? Or do I need to use the fields parameter and actually list all the fields, except the excluded field?
For example, if I have a database table (model), Company, with these fields:
id
name
street
city
state
zip
phone
Normally, $this->Company->find('all') would return all the fields. I want to exclude the phone field from the resultset.
$fields = array_keys($this->Company->getColumnTypes());
$key = array_search('phone', $fields);
unset($fields[$key]);
$this->Company->find('all', array('fields' => $fields));
For more info, please have a look at http://book.cakephp.org/2.0/en/models/additional-methods-and-properties.html#model-getcolumntypes
I can think of a couple ways to do this
Write out all the fields you want to include in the fields parameter. As mentioned in the comment, you can use $this->Company->schema to get all the fields programmatically rather than writing them out.
Unset the field you don't want after you get the data. You can do this in the model's afterFind function too.
What I want to do is trigger an action when one of the fields on my field collection is changed to a certain value. For example, my 'campaign' node has a field collection with a field called 'status' This status is a list containing 3 options; 'onboard', 'live', or 'dead'. When the field on a campaign node field collection is set to 'live' I want to trigger an action.
So I start by saying:
Events: After node is updated
Conditions: This is the bit I am struggling to work out as I cannot do a data comparison with this particular field.
Action: send email
How can I achieve this?
You may get it to work by using an approach similar to what is mentioned in comment # 4 of issue # 1315566, i.e.:
Create an "entity has field" condition on your Rule.
For the "Data Selector," select the entity that contains the field (in my case, a node). For the "Field" value, select the machine name of the field collection in question.
Go to your action. Using the "Data Selector" mode, you should be able to drill down through the entity in question to all the values contained within the field collection. In my case, the end result is "node:field-enrollee:field-school-district:0:tid"
In your case you try to do what is mentioned in step 3 above as a Rules Condition (instead of a Rules Action). So add a Rules Condition "Entity has field" (prior to being able to use it anywhere later on in your rule), which refers to your field collection field.
For way more details about this, refer to "How to iterate over all field collection items in the Rules module?" (which also includes a rule in export format you may want to experiment with, if you only adapt some machine names of the used fields).
This is my code:
$charities = explode(',',$this->data['Charity']['charities']);
foreach ($charities as $key=>$charity){
$data['Charity'][$key] = $charity;
}
$this->Grouping->id = $this->data['Charity']['grouping_id'];
if ($this->Grouping->save($data)){
//Great!
}else{
//Oh dear
}
The code is from an action that gets called by AJAX. $this->data['Charity']['charities'] is a comma separated list of ids for the Charity model, which HABTM Grouping.
The code works fine, except that Cake doesn't seem to check whether that charity is already associated with that grouping, so I end up with lots of duplicate entries in the join table. I can see that this will be a pain later on so I'd like to get it right now.
What am I doing wrong?
Thanks
A few things I spotted:
A. Is $this->data['Charity']['charities'] an array with named keys corresponding to the table columns? Because inside the foreach() loop, you are taking the key and putting it in the $data['Charity'] array. The result could be a wrong format. The $data array for Model saves is commonly formatted as $data['Charity']['NAME_OF_COLUMN1], $data['Charity']['NAME_OF_COLUM2], and so on for each column that wants to be saved. So, if the keys are numbers, then you could be having something like: $data['Charity'][0], $data['Charity'][1], which is wrong.
B. HABTM Associations are saved differently. What I do recommend, is that you take a look at the book's section on saving HABTM. I save a HABTM relation like this (supposing a relation between users and coupons):
$this->data['Coupon'] = array('id' => 1, 'code' = 'BlaBla');
$this->data['User'] = array('id' => 33);
$this->Coupon->save($this->data, false);
So, as you can see, the $data array has a subarray named after the foreign model ('User') with the columns+values that I want to save. Then I save this array to the Coupon model.
C. Be aware that CakePHP will always delete old records and insert new ones within the join table when it is 'updating' HABTM relations. To avoid this, you set the 'unique' field to false in the Model's $HABTM configuration.