I'm trying to figure out how to track the owners of real property. Investors specifically.
(I did spend hours researching and trying different things)
I'm using HABTM on the same model. (see below for why)
The difficulty I'm having is on the model->find. It only returns related entries if the id I'm searching for is in the first column of the relationship table.
In the entities table I have
1,Homer
2,Springfield Nuclear
3,Bart
In entities_relateds
2,1
2,3
(for the sake of argument, let's just assume that Bart grew up and went to work at the plant.
So both 1 & 3 are related to 2.)
If if do
$this->Entity->findById(2);
It looks great.
Array
(
[0] => Array
(
[Related] => Array
(
[id] => 2
[name] => Springfield Nuclear
[0] => Array
(
[id] => 1
[name] => Bart
)
[1] => Array
(
[id] => 3
[name] => Homer
)
)
)
)
However, if the values in the first row of entities_relateds are reversed...
1,2
2,3
I get
Array
(
[0] => Array
(
[Related] => Array
(
[id] => 2
[name] => Springfield Nuclear
[0] => Array
(
[id] => 3
[name] => Homer
)
)
)
)
It doesn't return the first row.
Doesn't matter if I do
$this->Entity->Related->findById(2);
It changes the array a bit, but still doesn't return the first row.
I'm wide open to alternate suggestions for how to solve this.
Thanks.
A bit more information here below.
Scenario:
It's pretty common to have people partner on deals and to own the property in either their own name, or any of several different companies. Partner A, Partner B, Company A, Company B. Any of these names could be on title, and really these are just aliases for the same 'group'.
So, I created a table called 'entities'. Each record can be either a real person, or a company. They share a lot of the same attributes, but most importantly, either type can be the legal owner of a piece of real property.
CREATE TABLE `entities` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
The relation table:
CREATE TABLE `entities_relateds` (
`entity_id` INT(11) NOT NULL DEFAULT '0',
`related_id` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`entity_id`, `related_id`)
)
Model HATBM
App::uses('AppModel', 'Model');
class Entity extends AppModel {
public $hasAndBelongsToMany = array(
'Related' => array(
'className' => 'Entity',
'joinTable' => 'entities_relateds',
'foreignKey' => 'entity_id',
'associationForeignKey' => 'related_id',
'unique' => 'keepExisting'
)
);
}
I would recommend you to try setting the recursive of the model to 1 like:
$this->Entity->recursive = 1
and then try to do the find.
If this not works I'd give a shot to containable behavior which is even better than messing up with the recursivity of model.
If you choose to work with ContainableBehavior your find would end up like this:
$this->Entity->find('all',
array(
'conditions'=>array('id'=>2),
'contain'=>array('Related')
)
);
UPDATE 1: Added containable code.
Related
When I am try pick a manufacturer name and upload the manufacturer logo image I want the image name to the manufacturer name. But the file name is always Array.
Can someone check the below code and tell me what is wrong?
View.ctp
<fieldset>
<label>Manufacturer</label>
<?php
echo $this->Form->input('manufacturer_id', array('options' => $manufacturers));
?>
</fieldset>
controller.ctp
$manufacturer_name=$this->Manufacturer->findById($product_data['Product']['manufacturer_id']);
$new_image_name = $manufacturer_name;
Cakephp 2 returns query result in the form of [ModelName] array.
You can access any field by using [ModelName][fieldName]
Array
(
[ModelName] => Array
(
[id] => 83
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 1
[field1] => value1
[field2] => value2
[field3] => value3
)
)
You can access Manufacturer name as (assuming manufacturer name is stored in name column)
$new_image_name = $manufacturer_name['Manufacturer']['name'];
For further reading:
https://book.cakephp.org/2.0/en/models/retrieving-your-data.html
I can't answer specifically as I don't know what the Manufacturer object contains but... try this, although it's a bit hacky. In controller.ctp add the print_r line:
$manufacturer_name=$this->Manufacturer->findById($product_data['Product']['manufacturer_id']);
$new_image_name = $manufacturer_name;
print_r($manufacturer_name);
It should show you how the $manufacturer_name variable is composed and then allow you to select what you're actually looking for, which I suspect will be something like:
$new_image_name = $manufacturer_name['some_index'];
I want to know how to retrieve the values from array that is looking like that:
Array ( [0] => Array
( [Group] => Array
( [id] => 1
[name] => admin
[created] => 2013-04-15 14:13:19
[modified] => 2013-04-15 14:13:19
)
[Admin] => Array
( [0] => Array
(
[id] => 1
[email] => iman#yahoo.com
[username] => iman
[password] => 9e217e2039912c40b0f179f801e2d3e9fe8eb32e
[active] => 1
[mobile] => 01000000000
[created] => 2013-04-15 13:56:02
[modified] => 2013-04-15 14:44:59
[group_id] => 1
[tokenhash] => e2e1bbffc40d3f909594a268f0f3ec127fabe5c00e01c5f0644a1950aa37e6103ad18542a8731a2ad9ade283916281977677523098cd25a296116d078fbbc231
[image] => d
)...
Thanks.
What have you tried already?
As far as I can see based on the limited information provided, you have two options; access a value directly by providing the relevant keys or looping over the array.
Say you want to access the name of the first Group in the array, which I presume is stored in a variable (called $yourArray in this example):
$yourArray[0]['Group']['name']
The result will be 'admin'.
Looping would give you the benefit of retrieving all the group names (or any other value):
foreach ($yourArray as $value) {
//Output the Group name
echo $value['Group']['name'];
//Output the Admin email
echo $value['Admin'][0]['email'];
}
But the above is all fairly standard PHP stuff and not specific to CakePHP. It might be good to read up on the basics of PHP as well, as CakePHP adds another layer of abstraction by providing all kinds of framework conventions and convenience methods.
To explain the issue I'm having, I'll use an example. Let's say that I'm building a system where students can sign up for an afterschool class, but an administrator has to approve the sign-up in order for it to be valid. So I have these models:
Calendar (belongs to "Teacher", hasAndBelongsToMany "Student")
Student (hasAndBelongsToMany "Calendar")
Teacher (hasMany "Calendar")
Now let's say I want to see a list of all of the unapproved sign-ups that are for ninth-graders. I want the list to include the calendar date, the student's name, and the teacher's name. I would do something like this:
$this->request->data = $this->Student->CalendarsStudent->find('all', array(
'conditions' => array(
'CalendarsStudent.is_approved' => null,
'Student.grade' => 9
)
));
The problem with the above code is that the returned array is missing the teacher's name:
Array
(
[0] => Array
(
[CalendarsStudent] => Array
(
[id] => 1274
[calendar_id] => 200
[student_id] => 872
[is_approved] =>
)
[Calendar] => Array
(
[id] => 200
[date] => 2012-12-17
[teacher_id] => 1
[total_slots] => 15
)
[Student] => Array
(
[id] => 872
[teacher_id] => 1
[first_name] => Billy
[last_name] => Smith
[grade] => 9
)
)
)
If I add 'recursive' => 2 to the find parameters, I get way too much information. $this->request->data[0]['Calendar'] will have [Teacher], which is what I want, but it will also have [Student], which I don't want. Also, $this->request->data[0]['Student'] will have subarrays that I don't want. It seems like Containable would fix this, but I can't get that to work either.
Any ideas?
Use CakePHP's [Containable Behavior]. It's amazing - easy to use and will return whatever you want it to.
Side note: If you're using "recursive" as anything other than -1 for ANYTHING, it should be a red flag. Containable is the absolute way to go as it lets you specify easily and exactly what data you want returned. Recursive will often cause memory issues and or other badness.
Best practice IMO: set $recursive = -1; in your AppModel.php and never set it to anything else...ever.
I have models Trip, Investment, and Person. A single trip hasMany investments, and every investment belongsTo one Person. When I say $this->Trip->find('all'); I get:
Array (
[0] => Array (
[Trip] => Array (
[id] => 1
[date] => 2012-10-25 13:00:00
)
[Investments] => Array (
[0] => Array (
[id] => 1
[person_id] => 1
[investment_type_id] => 2
[trip_id] => 1
[investment] => 55
)
[1] => Array (
[id] => 2
[person_id] => 2
[investment_type_id] => 1
[trip_id] => 1
[investment] => 40
)
)
)
)
I would like each investment to include the information about the person represented by person_id (So their id, their name, etc). I've tried all levels of recursion on the find('all') lookup with no luck.
have you defined both ways of association in all models?
eg. Trip hasMany Investments AND Investment belongsTo Trip
Investment belongsTo Person AND Person hasMany Investments
also query should be
$this->Trip->find->("all", array("recursive" => 2));
other thing what could be problem is if all necessary models are loaded in your controller
See cakePHP model associations (retrieving data deeper) for an alternative solution:
Use
$this->YourModelname->recursive = 3;
before querying.
Does anybody know how transform this query:
SELECT * from diminventory where partnumber='350964-B22' or partnumber in (SELECT partnumber from dimparts where parentpartnumber='350964-b22')
in a cakephp query
Thanks
I'm not 100% certain what you're asking for as yet, but here's a brief tutorial on cakephp querying.
$this->ModelName->query("SELECT * FROM tablename LIMIT 2;");
You query from the model, but you use the literal tablename. You use the SQL "AS" keyword to rename the keys of the resultant array.
Sample results:
Array
(
[0] => Array
(
[tablename] => Array
(
[id] => 1304
[user_id] => 759
)
)
[1] => Array
(
[tablename] => Array
(
[id] => 1305
[user_id] => 759
)
)
)
He is asking for Cakephp query not custom SQL query. In the controller:
$partnumber = $this->diminventory->find('all',array('conditions' => array('diminventory.partnumber' => '350964-B22')));
$this->set('partnumber',$partnumber);
set function passes a variable as $partnumber to the view. Then int view (which is .ctp file) you need to output the array.
foreach($partnumber as $partnumbers){
echo $partnumbers;
}
Make sure that diminventory table has 's' after the name otherwise it won't work as this is part of Cakephp's strict naming conventions.
Tutorial for find function:
http://book.cakephp.org/view/1018/find
To do it fully Cake'ish, you need to use CakePHP subquery:
$dbo = $this->User->getDataSource();
$subQuery = $dbo->buildStatement(
array(
'fields' => array('`Dimpart`.`partnumber`'),
'table' => $dbo->fullTableName($this->Dimpart),
'alias' => 'Dimpart',
'conditions' => array('`Dimpart`.`parentpartnumber`' => '350964-b22'),
),
$this->Dimpart
);
$subQuery = ' `DiminventoryEntry`.`partnumber` IN (' . $subQuery . ') ';
$subQueryExpression = $dbo->expression($subQuery);
$conditions[] = $subQueryExpression;
$conditions['DiminventoryEntry.partnumber'] = '350964-B22';
$result = $this->DiminventoryEntry->find('all', compact('conditions'));
Where Dimpart is your model for table dimparts, and DiminventoryEntry is your model for table diminventory (which is not actually Cake'ish, you should've renamed your table according to conventions).