Importing data in CakePHP - database

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.

Related

How to get the ID of the latest record just inserted?

I'm trying to insert data into 2 different tables with relationship .. for example student and hobby. so student->hasOne(hobby) and hobby->belongsTo(student).
I'm inserting all this info at one go ..in one form for your reference in doing something like this: one form submision to 2 controllers in laravel.
Now my question is how do I save the hobby with the same id as of student?
If I was saving student first then another form to save hobby then I can easily get the student_id first then I can save the hobby with the user id.
How about insertGetId()?
$studentId = DB::table('students')->insertGetId(
['name' => 'John']
);
Then you can use te ID for tasks that relate to other models:
DB::table('hobbies')->inset(
['student_id' => $studentId, 'hobby' => $hobby]
);
You can find more about queries here: https://laravel.com/docs/5.4/queries
You can submit to one controller. Easier. Then do
$student = Student::create([
'name' => $request->name,
...
]);
$hobby = Hobby::create([
'student_id' => $student->id,
'schedule' => $request->schedule,
...other data
]);
thx for the answers guys ..i did it by getstudentid() method and passing the student id...after creating the student.
You can insert it using the relation without even care about the id.
$hobby = auth()->user()->hobby()->create([
'hobby_column1' => 'bla bla bla',
'hobby_column2' => 'bla bla bla',
]);
In the example I use auth()->user(), but it can be any instance of User class.
Check Laravel Docs to better understand what you can do with relations.
Clearly you'll be able to get the id in $hobby, simply using $hobby->id once created.

Joining 3 tables in Cakephp

Using Cakephp 2.5.3 ... I have the following tables:
transactions (belongs to methods and deliveries)
id
delivery_id
method_id
methods (has many transactions)
id
name
deliveries (has many transactions)
id
date
In my delivery view I would like to see the method name for each delivery.
foreach ($deliveries as $delivery) {
echo $method['name'];
}
( a similar unanswered question is
here:)
I am (obv.) very new to Cakephp, What approach should I take to go about this? Thanks!
=========UPDATE==============
I ended up adding methods to the deliveries controller
$this->set('methods', $this->Method->find('all', array('recursive' => -1)));
And looped through the methods in my (read only) view :
//filtered method array for
$method['id'] == $delivery['Transaction']['0']['method_id'])
// got method name
$button_text = $method['name'];
It works fine but can anyone tell me if this may cause problems for me down the line?
use has many assotiations in Transaction model as -
public $hasMny = array('Method', 'Delivery');
then fetch them -
$this->set(
'methods',
$this->Method->find('all', array('contain' => array('Method', 'Delivery')))
);
you will get all the related result together.

Querying database with an array of related objects in laravel

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

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.
...
?>

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