Get threaded results for associated model in CakePHP - cakephp

I have 2 database-tables which are connected as followed:
ProjectProduct hasMany Bde
Bde belongsTo ParentBde / Bde hasMany ChildBde
The first association is new and shall be added into the application now. Since then I used $this->Bde->find('threaded') to get an threaded array of these records.
Now I need/want to query the ProjectProduct-table and wanted to use the containable-behavior to get all associated Bdes.
Now I'm wondering: Is it possible (in a Cake way) to still get threaded results with a call of find on ProjectProduct?
I tried doing $this->ProjectProduct->find('threaded', array('contain' => 'Bde')) but this will try to get threaded results on ProjectProduct.
I'm expecting an array like this:
Array (
[ProjectProduct] => Array (
[id] => 17,
[Bde] => Array (
[0] => Array (
[id] => 1,
[project_product_id] => 17,
[children] => Array()
)
)
)
)

Since I couldn't find any information how this can be done in one call or the "Cakish" way, I've done it like this:
$project_products = $this->Project->ProjectProduct->find('all');
foreach ($project_products as $key => $project_product) {
$project_products[$key]['Bde'] = $this->Project->Bde->find('threaded', array('conditions' => array('Bde.project_product_id' => $project_product['ProjectProduct']['id'])));
}
If someone has a better way in doing this I really appreciate any other ideas!

Related

Laravel Eloquent create ignores columns

I have an eloquent class with the protected set:
protected $fillable = array('user_id', 'key', 'value');
Yet if I do:
Foo::create(array('user_id'=>1, 'key'=> 1, 'value' => 'v'));
I get
Array
(
[query] => insert into `foo` (`updated_at`, `created_at`) values (?, ?)
[bindings] => Array
(
[0] => 2013-09-29 16:32:54
[1] => 2013-09-29 16:32:54
)
[time] => 0.42
)
On the other hand
Foo::insert(array('user_id'=>1, 'key'=> 1, 'value' => 'v'));
works flawlessly.
I ran into this issue. I was overriding the __construct method in my model object. After I removed my __construct method, everything seemed to go back to normal.
I can't say for sure this is what you are experiencing (and this answer is 6 months after your original question), but hopefully this will help someone else who comes across this same issue.

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

Cake Php Read function to retrieve result as 1-Dimensional array

Cake Php Read function to retrieve result as simple array
$result = $this->Model->read('id, name, title', $id);
It will result as
Array
(
[Model] => Array
(
[id] => 1
[name] => test
[title] => New Head title
)
)
It there any way to retrieve result array directly from query as below
Array
(
[id] => 1
[name] => test
[title] => New Head title
)
Without using any temp storage of a variable.
Just run the result through a Set::extract call, like this:
$result = $this->Model->read('id, name, title', $id);
$result = Set::extract('/Model', $result);
Set is a very powerful class, I suggest you read on it. :)
Cheers.
CakePHP purity aside (agree with other posters though)
Is find('list') what you are looking for?
$result = $this->Model->find('list', array('fields' => array('id', 'name', 'title'), 'conditions' => array('id' => $id), 'recursive' => 0 ));
Unless you're going to hack the Cake core, Cake will always internally return the results using the extra model key. So "without using any temp storage of a variable" is pretty much impossible, if you mean this in terms of "speed optimization" (in quotes, because it hardly makes any difference).
You can make it work simply with:
$result = current($this->Model->read('id, name, title', $id));
You could override the model's read method so it always does this internally (not recommended, it'll come to bite you one day). You could do so in the AppModel to have this behavior globally.

CakePHP removing special characters from this->params

I am using jQuery to pass data to the following URL in my cakephp 1.2 app:
$("#test").load("http://domain.com/controller/action/productID:2001642/questionID:2501322/value:C%2B%2B/questionType:3", function({
$("#test").fadeOut(3000);
});
In the controller when I
debug($this->params['named']);
it returns
Array
(
[productID] => 2001642
[questionID] => 2501322
[value] => C
[questionType] => 3
)
The URL part of $this displays
[url] => Array
(
[url] => deu/productanswers/updateoredit/productID:2001642/questionID:2501322/value:C /questionType:3
)
so that somewhere along the line the C++ or C%2B%2B is getting squished.
Does anyone have a solution or workaround please?
Cheers,
Taff
Although I would be very interested in a cakephp solution, I resorted to using $_SERVER['REQUEST_URI']
Definitely not a sexy solution
$tmp1 = explode('value:',$_SERVER['REQUEST_URI']);
$tmp2 = explode('/',$tmp1[1]);
$prod=$this->params['named']['productID'];
$ques=$this->params['named']['questionID'];
$value=urldecode($tmp2[0]);
Hope this helps someone in the future...

How to echo selected record?

i'm still a beginner, and guess it's a simple CakePHP question...
all i want is to echo retrieved data from database (one row is selected).
i have next code:
$cover_page = $this->Publication->find('list', array('conditions' => array('Publication.id' => $id)));
now, how can i echo field title from selected database row?
tnx in adv!!!
From the cookbook:
find('list', $params) returns an indexed array, useful for any use where you would want a list such as for populating input select boxes.
It will give a result as below
Array
(
//[id] => 'displayValue',
[1] => 'displayValue1',
[2] => 'displayValue2',
[4] => 'displayValue4',
[5] => 'displayValue5',
[6] => 'displayValue6',
[3] => 'displayValue3',
)
Since in your code you've specified the id to make the result only one record
,you may not really need to use it, though you can access the title with $cover_page[$id] if you've set the right displayfield.A normal way to do your work would be
$cover_page = $this->Publication->find('first', array('conditions' => array('Publication.id' => $id)));
or
$cover_page = $this->Publication->findById($id);
Both of them can get the title by
$cover_page['Publication']['title']
You access it like this (CakePHP creates an array of the database result):
echo $cover_page['Publication']['title'];
To get it into the view do:
$this->set('cover_page',$cover_page);

Resources