views:

83

answers:

4

I have been trying to figure out how to do this and it seems that its not something that many people are trying to do in cakephp or I am just completely misunderstanding the documentation.. I am using the following query below to get a field value so I get a value where the "findbycreated" is 0... this part works fine

$unregisteredemail = $this->Testmodel->findBycreated('0');
$emailaddress = $unregisteredemail['Testmodel']['emailaddress'] ;
$emailpassword = $unregisteredemail['Testmodel']['password'] ;

But now, after I do some things with this data that I retrieved, I want to mark a field, in the same row, in the same model / table as a value of '1' to indicate that an action has taken place (email address has been successfully created, for example)... I just can't figure out how to do this in cakephp despite my efforts of going through the documentation and searching, this should be rather simple, I am tempted, at this point, to just use a regular mysql query as its a simple query.. basically the query is (please excuse my syntax as I haven't used direct mysql queries in a while) "update (database / table) set 'created'='1' where 'emailaddress'=$emailaddress"

Or I could use the row ID, if needed, as cakephp seems to prefer this, but still can't get how to do this.. this is my attempt below that is not working:

// update database to show that email address has been created
$this->Testmodel->read('emailaddress', $this->Testmodel->findBycreated('0'))
$this->Testmodel->id = 1;
$this->Testmodel->set(array(
            'created' => '1'
            ));

 $this->Testmodel->save();
+3  A: 

In this situation I would let Cake deal with the id's and just focus on changing the row data and resaving it to the database

$row = $this->Model->findBycreated(0);
$row['Model']['emailaddress'] = 1;
$this->Model->save($row);

This way, you don't have to worry about the id's, as the id will be in your dataset anyway, so just change what you want and then tell Cake to save it.

Ninja edit, Be sure that you are returning a full row with an id from your findBycreated() method.

DavidYell
this returns an error "SQL Error: 1062: Duplicate entry '$key' for key 'PRIMARY' "So I think this is trying to insert rather than update
Rick
`pr()` your data first to ensure that there is an id in the row. Also you'll want to ensure that you have only 1 row returned.
DavidYell
+2  A: 

There're many ways to do your work.I suggest you to read the cookbook about saving data in cakephp.And besides david's solution another simple way would be

$this->Testmodel->id = 1;  
$this->Testmodel->saveField('created' =>'1'); 
SpawnCxy
as I said, I did read it.. I am having some trouble interpreting it, I apologize if the question seemed really simple, its just that the cookbook isn't exactly worded as clearly as it could be IMO
Rick
@Rick,well,the cookbook will be your good friend soon i think.just take your time:)
SpawnCxy
I tried your code and I get an error: Parse error: syntax error, unexpected T_DOUBLE_ARROW in /var/www/site1/app/controllers/hushmail/hushmails_controller.php on line 121 so I think there must be some error in using the =>
Rick
+2  A: 

There are, as you can see from the previous answers, several ways to achieve the same end. I'd just like to explain a little about why your way didn't work.

In the model, CakePHP has abstracted the database row(s) into an array according its implementation of ORM . This provides us with a handy way of manipulating the data and chucking it around the MVC architecture.

When you say:

$this->Testmodel->set(array(
            'created' => '1'
            ));

You are dealing directly with the model, but the data is actually stored, as an array, in a class variable called $data. To access and manipulate this data, you should instead say:

$this->data['Testmodel']['created'] => '1';

The reason for specifying the model name as the first index is that where associated tables have been retrieved, these can be accessed in the same way, so you might have , for instance:

Array([Testmodel] => Array ([id] => 1,
                            [created] => [1],
                            ...
                           )
      [Relatedmodel] => Array ([id] => 1,
                               [data] => asd,
                            ...
                           )
     )

...and so on. Very handy.

Now, when you use $this->MyModelName->save() with no parameters, it uses $this->data by default and uses the part of the array of data appropriate to the model you are calling the save method on. You can also pass an array of data, formatted in the same way if, for some reason, you don't (or can't) use $this->data.

Your use of the method read() is incorrect. The first parameter should be null, a string or an array of strings (representing fieldname(s)). The second parameter should be the id of the record you wish to read. Instead, for param 2, you are passing the result of a find, which will be an array. The result, which you are not capturing, will be empty.

I would write your code like:

$this->data = $this->Testmodel->read('emailaddress',1); 
$this->data['Testmodel']['created'] = 1;
$this->Testmodel->save();

or more succinctly:

$this->Testmodel->id = 1;
$this->Testmodel->saveField('created', 1);
Leo
Thanks for the clarification, I understand the issue now.. I just wish there were a few more examples in the cakephp cookbook but I guess now that I think about it doing it in a manner like the answers here have described is pretty straightforward
Rick
Actually.... I tried this, and its still creating a new field, not updating the one with the ID that I specify, I guess I am still struggling with why it always inserts a new field rather than updating the one I want
Rick
Leo
A: 

Ok, I think I finally found the solution, I was able to get this to work:

$this->Test->updateAll(
  array(
    'Test.field' => 'Test.field+100'
  ),
  array(
    'Test.id' => 1
  )
);

I think you have to use updateAll as anything else will just create a new row.. basically CakePHP, for whatever reason, neglected to include a function for updating just one field so you have to put it into an array with the updateAll to make it work...

the +100 is where the updated info goes, so in this case "100" would be what the field is updated to.

Rick