I'm working with CakePHP 3.2. Here is my find query:
$a=$this->A->find('all', ['where' => [ 'b=='=>5, 'c>'=>1000 ]])->first();
// For debuging what I receive:
$data=$a->toArray();
print_r($data);
I'd like to select first record in 'A', whose column 'b' equals 5 and column 'c' is grater than 1000. What am I doing incorrectly? The above query returns all records from 'A' table.
Use conditions instead of where
$a=$this->A->find('all', ['conditions' => ['b'=>5, 'c >'=>1000]])->first();
simply
$a = $this->A->find()
->where([ 'b' => 5, 'c >' => 1000 ])
->first();
debug($a)
you don't need to call toArray() since first already returns a single entity
It should be like this:
$data = $this->A->find()->where(['b' => 5, 'c >' => 1000])->first();
Use conditions instead of where
$query = $articles->find('all', [
'conditions' => ['Articles.title LIKE' => '%Ovens%']
]);
$result = $query->toArray();
Related
I'm working on CakePHP 3.2
I want to use an array in the query WHERE IN ()
The code is as
$filter_p_t = $this->request->query('p_t');
$pros10 = $this->Products->find()
->where([
'SellerProducts.stock >' => 0,
'SellerProducts.status' => 1,
'Products.p_status' => 1,
])
->contain([
'SellerProducts',
'ProductTypes.Subcategories.Categories',
]);
Here $filter_p_t is an array from url with parameter
/products/display/1?p_t[]=1&p_t[]=86
I want to include $filter_p_t in to the where condition to find all IN(1,86)
How can I use php array to the WHERE IN condition in CakePHP 3?
You can use the IN keyword directly after the column. This is assuming that $filter_p_t is an array like array(1, 86).
->where(['id IN' => $filter_p_t]);
http://book.cakephp.org/3.0/en/orm/query-builder.html#automatically-creating-in-clauses
I have a query
$p = $this->Products
->findById($id)
->select(['name'])
->contain(['Categories.Sizes' => function($q) {
return $q->select(['id', 'name']);
}
]);
which is only returning product's name and not the Size of the product's category. But if the remove the select function which accepts the field names then it delivers also the Sizes
Is there any solution for that?
According to the CakePHP 3 book, in the area "Selecting Rows From A Table", you can specify which fields you want returned by including them in a select array:
$query = $articles
->find()
->select(['id', 'name']) // <-- Notice this line
->where(['id !=' => 1])
->order(['created' => 'DESC']);
So for yours, you're limiting the fields that are returned because you're specifying that you only want the 'name' field.
I am converting some finds from cakephp2 to cakephp3.
I need to search on a first name and surname on a tutors table that are stored on different columns. According to the docs I needed to have a LEFT join bewtween the tables. I have used an or condition with 2 fields but it works like and 'and' condition if both parameters have a value.
My issue is
q1) I cant get the data with just the first name only , and the surname is null.
q2) I need to pass both first name and surname to get just those data with that name.
Not sure how to do this in cakephp3.
eg $a5='fred'; //just want all first names like fred
$a6=null; //sometimes this will be filled
$a3='2015-05-30';
$a4='2016-06-01';
$query3 = $this->Lessons->find()
->contain(['Tutors'])
->select(['lessons.id','lessons.lesson_date','tutors.id','tutors.first_name','tutors.last_name' ])
->where(['Lessons.lesson_date >' => $a3,'Lessons.lesson_date <' => $a4,
'OR' => [['tutors.first_name like' => '%'.$a5.'%'], ['tutors.last_name like' => '%'.$a6.'%']],
]);
foreach ( $query3 as $row) {
debug($row->toArray());
}
I didnt understand the docs on this point.
http://book.cakephp.org/3.0/en/orm/query-builder.html#advanced-conditions
UPDATE- tried this and this also just gives all the data with either 'at' or 'to' but it should be any names with both 'at' and 'to' in them.
$query3 = $this->Lessons->find()
->contain(['Tutors','Subjects', 'TutoringTypes','Terms','Students'])
->select(['lessons.id','lessons.lesson_date','tutors.id','tutors.first_name','tutors.last_name',
'subjects.id','subjects.name','terms.id','terms.title'])
->where(['Lessons.lesson_date >' => $a3,'Lessons.lesson_date <' => $a4])
->orWhere(function ($exp) {
return $exp->and_([
'tutors.first_name like' => '%an%',
'tutors.last_name like' => '%to%',
]);
});
Pay attention to the generated SQL. You either see it in DebugKit or debug it by calling $query->sql(). You're building a wrong query:
You generate OR ((... AND ...)) because you're using an and_. You probably want ... OR ....
->orWhere(function ($exp) {
return $exp->and_([
'tutors.first_name like' => '%an%',
'tutors.last_name like' => '%to%',
]);
});
You probably want OR. But passing the array directly to orWhere() would work as well.
How do you make it where in clause in new CakePHP? I'm trying:
$restaurants->find()->where(['id' => $r_ids])->all();
Where $r_ids is array of ids I need in my query, but this doesn't work as expected.
With CakePHP 3.x it's now necessary to either indicate the data type, which for an array of values need to have [] appended to the type:
$query = $articles
->find()
->where(['id' => $ids], ['id' => 'integer[]']);
or to explicitly make use of the IN keyword:
$query = $articles
->find()
->where(['id IN' => $ids]);
See also
Cookbook > Database Access & ORM > Query Builder > Automatically Creating IN Clauses
Try this one for CakePHP 3.x
$query = $restaurants
->find()
->where(['id IN' => $r_ids]);
$query->all();
You can also use the short syntax:
$result = $restaurants->find('all',
['conditions' => ['id IN' =>$r_ids]]
)->all();
In Cakephp 3.x, If you have multiple where conditions then your query will be as below:
return $this
->find()
->contain([
'XYZ.Articles',
'YYY.Managers',
'ZZZ.Readers',
])
->where([
'ID' => $ids,
'READER.STATUS' => $xyz,
],[
'ID' => 'integer[]'
])
;
I am using cakephp 2.5 and I have an array that I wish to update many records at once in the Page model. I can't seem to get the format of the array correct. I get the error:
Notice (8): Undefined index: newOrder [APP/Controller/PagesController.php, line 133]
$newOrder = array(
'Page' => array(
0 => array(
'id' => 3,
'order' => 0),
1 => array(
'id' => 4,
'order' => 0),
2 => array(
'id' => 7,
'order' => 0
)
));
$this->Page->updateAll($newOrder);
One of the parts I think I am missing is using 'data' as part of the array. But I am unsure where to place it.
I have also tried:
$this->Page->updateAll($newOrder['Page']);
You should use saveMany for your requirement. Find the explanation below -
updateAll
updateAll(array $fields, array $conditions) - is used to update one or more records with the same value based on a condition or multiple conditions. eg: If you want to update all your pages & set all of them to order = 0, you can use updateAll without passing the primary keys -
$this->Page->updateAll(
array('Page.order' => 0)
);
If you want to update some pages based on a condition you will do something like -
$this->Page->updateAll(
array('Page.order' => 0),
array('Page.type' => 'PROMOTED')
);
Assuming you have a type field in your page model, the above query will set order 0 for all pages with type PROMOTED
Ref - http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-updateall-array-fields-array-conditions
saveMany
Now if you want to update some specific records with some specific values which you want to create in an array, you should use a saveMany(array $data = null, array $options = array())
To save/update multiple records using a data array, you should first create the data array in this format -
$data = array(
array('Page' => array('id' => 1, 'order' => 0)),
array('Page' => array('id' => 2, 'order' => 0)),
array('Page' => array('id' => 3, 'order' => 0))
);
$this->Page->saveMany($data);
Now you can use saveMany to update the three records with the given id(primary key) with order 0. Note if you don't pass primary keys i.e id in the arrays, saveMany will just create new records for the given array.
Ref - http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savemany-array-data-null-array-options-array