Querying database with an array of related objects in laravel - arrays

I would like to query some offers by skills from my database with laravel.
The relationship between an offer and its skills is a belongsToMany relationship.
How to get all offers that match an array of skills from the database ?
To be clearer here is some code I started to write :
$skills = Input::get('skills');
$offers = Offer::with(
array(
'skills' => function($query){
// here I'd like to select skills from array $skills
$query->where(?????);
}
)
)->get();
Thanks in advance !

Use whereIn with array
http://laravel.com/docs/queries#selects
$skills = Input::get('skills');
$offers = Offer::with(array('skills' => function($query) use ($skills){
$query->whereIn('skill', $skills);
}))->get();

Related

Count Users connected in CakePHP Listing

I have 3 Models (Adresses(orders) / Users / Cities)
and I connect them via adresses_users(I know adresses is supposed to be with two d´s :/) and cities_users.
Now I have an action in Adresses Controller which should give me a list for all the cities available and I want a count how many users are in that city (by the cities_users connection.
//Get all cities
$cities = $this->Cities->find('list', [
'keyField' => 'id',
'valueField' => function ($cities) {
return $cities->get('full_info');
}
,'order' => ['name' => 'asc']])
->contain(['Users']);
I got so far, but I don´t know where I can use the count function for all the containing users. Anyone an idea or documentation link (https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#finding-key-value-pairs)
You can construct query like this,
$query = $this->Cities->find();
$query->select(['users_count' => $query->func()->count('Users.id'),
'city_name' => 'Cities.name']);
$query->leftJoinWith('CitiesUsers');
$query->group('Cities.id');
//debug($query->sql()); debug($query); //to check whether correct sql constructed
//debug($query->toArray());
This code is not tested, i wrote it to provide example.

cakephp saving data for a related model's related model (not typo)

I've run into a bit of a problem saving data in cake php.
here are the models/relationships.
District hasMany Departments
Department hasMany Groups
I am in a view for creating new district, in which I've allowed the user to create multiple new departments. while creating each department, the user may create multiple groups for that dept. Now the trouble is I'm unsure of how to save the group data.
for each department that is created on the fly, im using the multiple index method for the inputs (i.e. "Department.0.name", Department.0.type) so this will be a cinch to save using the saveAll method. However, for each group that is created, i will need a department_id, and since none of the District's departments have yet been saved, they don't have an id. how can i save this new district's data, saving the new departments, and their associated new created groups? is there a way that i can address the name attribute of the group inputs that will create the proper association, something like "Department.0.Group.0.name", for instance?
Thanks in advance!!! if anything is unclear, please don't hesitate to say so, I'll be glad to rephrase.
What does your POST data array look like?
<?php
debug($this->data);
?>
If it is not in the correct format, the associated models won't get saved.. Cake knows to grab the "lastInsertId()" of the models which haven't been saved yet, so you don't have to worry about those... What i'm not sure about, and the docs don't really go into, is how deep the save goes. The example provided is as follows:
$this->data =
Array
(
[Article] => Array
(
[title] => My first article
)
[Comment] => Array
(
[0] => Array
(
[comment] => Comment 1
[user_id] => 1
)
[1] => Array
(
[comment] => Comment 2
[user_id] => 2
)
)
)
$this->Article->saveAll($this->data);
This is the correct structure (cakephp 1.3) for saving associated models of a 'hasMany' relationship, but i'm not sure if it goes any deeper than one child.
One thing that comes to my mind is to build the array according to the format above, but leave the parent model out. Then manually save the parent model data, grab the ::getLastInsertId(); then do a saveAll on departments and groups.
[UPDATE]
I just tested your theory and it will work the way you intend.
<?php
echo $this->Form->input('Department.0.Group.0.name');
?>
Will produce:
<input name="data[Department][0][Group][0][name]" type="text" id="Department0Group0name">
[UPDATE 2]
I did some exploring in lib/Cake/Model/Model.php and found this:
<?php
...
public function saveAssociated($data = null, $options = array()) {
...
... // code omitted.
...
if ($options['deep']) { // This will recurse infinitely through all associations
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
}
...
...
... // code omitted.
...
?>

Importing data in CakePHP

I took a certain system of relations in my database and when I started write models I came to some problem. First maybe I'll show my database schema.
##USERS##
id
##CVS##
id
user_id
##SKILLS##
id
cv_id
user hasOne cv
cv belongsTo user
cv hasMany skill
skill belongsTo cv
This solution seemed to be correct, but when I tried to get cv_id in skills table then I had to write something like this:
$cv_id = $this->Skill->find('first', array('user_id' => $this->Auth->user('id')));
$this->request->data['Skill']['cv_id'] = $cv_id['CV']['id'];
I find it very messy solution. Is there any better way to get this information in cakePHP or maybe I should change my relations between tables? What should I do in this case?
You can use the following code:
$this->Skill->virtualFields['cvid'] = 'CV.id';
$cv_id = $this->Skill->find('first', array('user_id' => $this->Auth->user('id')));
$this->request->data['Skill']['cv_id'] = $cv_id['Skill']['cvid'];
---------------------- OR -----------------------------
$this->Skill->virtualFields['cv_title'] = 'CV.title';
$cv_id = $this->Skill->find('first', array('user_id' => $this->Auth->user('id')));
$this->request->data['Skill']['cv_title'] = $cv_id['Skill']['cv_title'];
---------------------- OR -----------------------------
$this->Skill->virtualFields['cv_title'] = 'CV.title';
$this->request->data = $this->Skill->find('first', array('user_id' => $this->Auth->user('id')));
You can dynamically add virtualFields using above syntax.
Here is the explaination.
Hope it will work for you.

CakePHP find query across multiple datasources

I am tring to do the following:
My 'Company' Models are being stored in a 'default' datasource. In to
model I set the var $useDbConfig = 'default';
My 'User' Models are being stored in another datasource called
'users_db'. In this model I set the var $useDbConfig = 'users_db';
There is a 'belongsTo' relationship between 'Company' and 'User' models.
I want to do a recursive find query that brings back all users for each company in one go. I have the feeling that I cannot do this with Cake as it currently is.
When I try the following:
$res2 = $this->Company->find('all', array(
'conditions' => array('Company.id' => 1),
'recursive'=>2
));
I get a message that it cannot find the users table(its looking in the default source):
Error: Table user_groups for model User was not found in datasource default.
Is there any way I can do this?
Many thanks for any help you can provide.....
kSeudo.
Why not replace the your original statement by this:
$this->loadModel('User');
$res2 = $this->User->find('all',
array( 'conditions' => array( 'User.company_id' => 1 ) ));
This will produce the results you want.
Otherwise, if you wanted something tidier, you could add a fetch_users() function to your Company class that implemented a similar logic.
Ok, problem solved. Once I set the datasource in the model correctly everything seems to work fine.
Thanks guys

Select from a table where associated table fieldname = 'x' in Cake PHP

In CakePHP, I have two tables, Countries & Networks. They have a HABTM relationship and are joined by countries_networks.
I'm trying to get all countries from the countries table where the 'name' field in Networks = 'o2'
I've realised I can't do this using a basic find(), so I've been experimenting with the containable behaviour. I have managed to restrict the returned data, but it looks as though 'containable' doesn't exactly work as I want. Heres my code:
$countries = $this->Country->find('all', array('contain' => array(
'Network' => array(
'conditions' => array('Network.name =' => "o2"),
)
)));
This query however returns ALL countries, and the Network.name if its 'o2'. What I really need to do is return ONLY the countries that have a Network.name of 'o2', and no others.
Can anyone help? Thanks.
"=' =>"
What is it? there is no needed to use "=" symbol after "Network.name"
Your query returns you exactly what your ask.
Try to select from Network.
$countries = $this->Country->Network->find('first', array(
'conditions' => array('Network.name' => "o2"),
'contain' => array('Country')
));
$countries = $countries['Country'];
You should be able to do something like this:
$this->Country->hasAndBelongsToMany['Network']['conditions'] = array('Network.name'=>'o2');
$myCountries = $this->Country->find('all');
I haven't tested this, but it should get you pretty close to where you need to be.
Also, bear in mind that changing the hasAndBelongsToMany array like this will affect all subsequent queries against that model during the current page load (but it will be reset the next time the model is instantiated).
I'm on my way out the door, so sorry for the brief explanation.
I think what you want is a HABTM relationship, but to be able to filter based on the associated model's data. To do this, check out the "Containable" behavior in Cake's manual. Pretty sure that's what you're after.

Resources