简体   繁体   English

CakePHP根据同一行中的其他值更新字段值吗?

[英]CakePHP update field value based on other value in same row?

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 我一直在尝试找出方法,似乎它不是很多人在cakephp中尝试做的事情,或者我只是完全误解了文档。我在下面使用以下查询来获取字段值,因此我得到一个值,其中“ findbycreated”为0 ...这部分工作正常

$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" 但是现在,在对检索到的数据进行某些处理之后,我想将同一模型/表中同一行,同一行中的字段标记为值“ 1”,以指示已执行操作(电子邮件例如,已经成功创建了一个地址)...尽管我努力浏览了文档并进行了搜索,但我仍然不知道如何在cakephp中执行此操作,这应该非常简单,在这一点上,我很感兴趣,只需使用常规的mysql查询作为其简单查询即可。基本上,该查询是(请原谅我的语法,因为我已经有一段时间没有使用直接mysql查询了)“ update(数据库/表)设置为'created'='1 '其中'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: 或者,如果需要的话,我可以使用行ID,因为cakephp似乎更喜欢这样做,但是仍然无法做到这一点。.这是我在下面的尝试不起作用:

// 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();

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 在这种情况下,我将让Cake处理ID,只专注于更改行数据并将其重新保存到数据库中

$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. 这样,您不必担心ID的问题,因为ID仍然会存在于您的数据集中,因此只需更改所需内容,然后告诉Cake保存它即可。

Ninja edit, Be sure that you are returning a full row with an id from your findBycreated() method. 忍者编辑,请确保您从findBycreated()方法返回的id为整行。

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 . 在该模型中,CakePHP根据其ORM的实现将数据库行抽象为一个数组。 This provides us with a handy way of manipulating the data and chucking it around the MVC architecture. 这为我们提供了一种方便的方式来处理数据并将其围绕MVC架构进行处理。

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. 您正在直接处理模型,但是数据实际上作为数组存储在名为$ 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. 现在,当您使用不带参数的$this-> MyModelName ->save()时,默认情况下它将使用$ this-> data并使用与您要调用save方法的模型相对应的数据数组的一部分。 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 . 如果由于某种原因而不(或不能)使用$this->data ,您还可以传递以相同格式格式化的数据数组。

Your use of the method read() is incorrect. 您对方法read()的使用不正确。 The first parameter should be null, a string or an array of strings (representing fieldname(s)). 第一个参数应该为null,一个字符串或一个字符串数组(代表fieldname(s))。 The second parameter should be the id of the record you wish to read. 第二个参数应该是您希望读取的记录的ID。 Instead, for param 2, you are passing the result of a find, which will be an array. 相反,对于参数2,您将传递查找结果,该结果将是一个数组。 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);

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 有很多方法可以完成工作。我建议您阅读有关在cakephp中保存数据食谱 。除大卫的解决方案外,另一种简单的方法是

$this->Testmodel->id = 1;  
$this->Testmodel->saveField('created' =>'1'); 

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... 我认为您必须使用updateAll,否则其他任何东西都只会创建一个新行。.基本上,无论出于何种原因,CakePHP都忽略了仅包含更新一个字段的函数,因此您必须将它放入带有updateAll的数组中工作...

the +100 is where the updated info goes, so in this case "100" would be what the field is updated to. +100是更新信息所在的位置,因此在这种情况下,字段将更新为“ 100”。

In cakephp 3.x the syntax seems to be different. 在cakephp 3.x中,语法似乎有所不同。 This is what worked for me in 3.x: 这是在3.x中对我有效的方法:

$this->Tests->updateAll(
    [
        'Tests.field = Tests.field+100'
    ],
    [
        'Tests.id' => 1
    ]
];

The difference is that the entire expression needs to be in the value of the first array. 区别在于整个表达式需要位于第一个数组的值中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM