Huston, I have a problem;
Problem
So, I have a EAV models in my database, Entity, Attribute, Value. The relations between are:
Production hasMany Entity -> Entity belongsTo Production
Entity hasMany Attribute -> Attribute belongsTo Entity
Attribute hasMany Value -> Value belongsTo Attribute
The table values
---value (INT 3) ,
---label (VARCHAR 65),
---id (INT 11 AI)
I Can save the relations in my database, but, my application needs to return the SUM of Value.value a specific production, example:
The final user, need the consolidate of as Production by month of created. So, now, my application return is this:
(int) 0 => array(
'Production' => array(
'myconditions' => 'HereIsNotAProblem'
),
'Entity' => array(
(int) 0 => array(
'id' => '11',
'label' => 'Acompanhamento Familiar',
'production_id' => '8',
'Attribute' => array(
(int) 0 => array(
'id' => '33',
'label' => 'Nascidos vivos no m?s',
'entity_id' => '11',
'Value' => array(
(int) 0 => array(
'id' => '1',
'label' => '< 2500g',
'value' => '0',
'attribute_id' => '33'
),
)
)
)
)
I need to return:
(int) 0 => array(
'Production' => array(
'myconditions' => 'HereIsNotAProblem'
),
'Entity' => array(
(int) 0 => array(
'id' => '11',
'label' => 'Acompanhamento Familiar',
'production_id' => '8',
'Attribute' => array(
(int) 0 => array(
'id' => '33',
'label' => 'Nascidos vivos no m?s',
'entity_id' => '11',
'Value' => array(
(int) 0 => array(
'id' => '1',
'label' => '< 2500g',
'SUM' => 'TOTAL_SUM',
'attribute_id' => '33'
),
)
)
)
)
How I do this?
So when you query your data you need to left join Values to Attributes and use SUM expression. You can see similar example here, but using COUNT: https://book.cakephp.org/3.0/en/orm/query-builder.html#using-leftjoinwith
Related
I have the following CakePHP code; I want it to return all rows (two in this case)
public function orderdetails($orderId)
{
$Productsaleslist = $this->Productsales->find('all', array(
'joins' => array(
array(
'table' => 'product',
'alias' => 'prod',
'type' => 'INNER',
'conditions' => array(
'prod.id = Productsales.product_id'
)
),
array(
'table' => 'sales_order_address',
'alias' => 'sod',
'type' => 'INNER',
'conditions' => array(
'sod.id = Productsales.sales_order_address_id'
)
),
),
'fields' => array(
'Productsales.*',
'prod.name',
'prod.image_url',
'sod.*'
),
'conditions' => array(
'Productsales.product_sales_slno' => $orderId
)
)
);
$this->set('Productsaleslist', $Productsaleslist);
}
$orderId comes from a URL parameter, and it contains the value of product_sales_slno (RAJ201701211485025418). This should retrieve two integers, but I'm only getting one as shown below.
How can I fix this?
I have 3 Entities:
Appointment
Doctor (extend fe_users)
Specialization
Dependencies:
Each appointment has exactly one doctor
Each doctor has at least one specialization
Each appointment has at least one specialization - but it can't be
one that its doctor doesn't have
My goal: After a doctor is selected you can choose which specialization of the doctor will be used in order to categorize the appointment - but multiselect should also be possible.
Edit: I came up with this sql to make it clearer what I want in my Select-Field:
SELECT s.name
FROM
tx_appointments_domain_model_specialization s,
fe_users fe,
tx_appointments_doctor_specialization_mm ds,
WHERE fe.username = "###REC_FIELD_doctor###"
AND ds.uid_local = fe.uid
AND s.uid = ds.uid_foreign;
So the part of my TCA of Appointment looks like this now:
It's pretty much all generated by the extension builder except the 'foreign_table_where' in doctor which I found out somehow. But I can't wrap my head around how to set the specialization now.
'doctor' => array(
'exclude' => 1,
'label' => 'doctor',
'config' => array(
'type' => 'select',
'foreign_table' => 'fe_users',
'foreign_table_where' => "AND FIND_IN_SET('1', fe_users.usergroup) ORDER BY fe_users.last_name ASC, fe_users.first_name ASC",
'minitems' => 0,
'maxitems' => 1,
),
),
'specialization' => array(
'exclude' => 1,
'label' => 'specialization',
'config' => array(
'type' => 'select',
'foreign_table' => 'tx_appointments_domain_model_specialization',
'MM' => 'tx_appointments_appointment_specialization_mm',
'size' => 10,
'autoSizeMax' => 30,
'maxitems' => 9999,
'multiple' => 0,
'wizards' => array(
'_PADDING' => 1,
'_VERTICAL' => 1,
'edit' => array(
'module' => array(
'name' => 'wizard_edit',
),
'type' => 'popup',
'title' => 'Edit',
'icon' => 'edit2.gif',
'popup_onlyOpenIfSelected' => 1,
'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1',
),
'add' => Array(
'module' => array(
'name' => 'wizard_add',
),
'type' => 'script',
'title' => 'Create new',
'icon' => 'add.gif',
'params' => array(
'table' => 'tx_appointments_domain_model_appointment',
'pid' => '###CURRENT_PID###',
'setValue' => 'prepend'
),
),
),
),
),
I know I could use something like 'foreign_table_where' => ..."###REC_FIELD_doctor###"... but I have no idea how the whole SQL should look like to get only the doctor's specializations showing.
And I'll probably have to add something like this in ext_tables.php which I got from this answer similar to my problem:
$TCA['tx_appointments_domain_model_appointment']['ctrl']['requestUpdate'] .= ',doctor';
I'm using cakePHP 2.6.4.
I have two tables AgentChat and AgentChatMember.
AgentChat hasMany AgentChatMember,
AgentChatMember belongsTo AgentChat.
AgentChat have: id, team_id, agent_chat_member_count fields.
AgentChatMember have: id, agent_chat_id, user_id fields.
I want to find AgentChat by chat_team_id and agent_chat_member_count,
and AgentChatMember as contain with user_id conditions.
$options['contain'] = array('AgentChatMember');
$options['conditions']['AgentChat.agent_chat_member_count'] = count($user_ids);
$options['conditions']['AgentChat.chat_team_id'] = $chat_team_id;
$res = $this->AgentChat->find('first', $options);
and $res is:
'AgentChat' => array(
'id' => '1',
'agent_message_count' => '0',
'agent_chat_member_count' => '2',
'chat_team_id' => '14',
'created' => '2015-05-06 09:52:31',
'updated' => '2015-05-06 09:52:31'
),
'AgentChatMember' => array(
(int) 0 => array(
'id' => '1',
'agent_chat_id' => '1',
'user_id' => '26',
'created' => '2015-05-06 09:52:31'
),
(int) 1 => array(
'id' => '2',
'agent_chat_id' => '1',
'user_id' => '21',
'created' => '2015-05-06 09:52:31'
)
)
By this i get what i want except fact i cant set user_id condition to AgentChatMember like this: $options['conditions']['AgentChatMember.user_id'] = $user_ids;
When i'm using joins instead of contain i can set user_id conditions, but i get result like this:
(int) 0 => array(
'AgentChat' => array(
'id' => '1',
'agent_message_count' => '0',
'agent_chat_member_count' => '2',
'chat_team_id' => '14',
'created' => '2015-05-06 09:52:31',
'updated' => '2015-05-06 09:52:31'
),
'AgentChatMember' => array(
'id' => '2',
'agent_chat_id' => '1',
'user_id' => '21',
'created' => '2015-05-06 09:52:31'
)
),
(int) 1 => array(
'AgentChat' => array(
'id' => '1',
'agent_message_count' => '0',
'agent_chat_member_count' => '2',
'chat_team_id' => '14',
'created' => '2015-05-06 09:52:31',
'updated' => '2015-05-06 09:52:31'
),
'AgentChatMember' => array(
'id' => '2',
'agent_chat_id' => '1',
'user_id' => '26',
'created' => '2015-05-06 09:52:31'
)
),
...
Its possible to get multiple records join into one table or contain with conditions on it?
How can i achieve that?
You can pass conditions to the contain:-
$res = $this->AgentChat->find(
'first',
array(
'contain' => array(
'AgentChatMember' => array(
'conditions' => array(
'AgentChatMember.user_id' => $userIds
)
)
),
'conditions' => array(
'AgentChat.agent_chat_member_count' => count($userIds),
'AgentChat.chat_team_id' => $chatTeamId
)
)
);
Just as an aside, you should really be camel casing your variables in CakePHP. See the Coding Standards in the documentation.
I'm trying to save some data using HasAndBelongsToMany relations.
Here are my tables :
commercials:
id (int) AI
name (varchar)
showrooms:
id (int) AI
name (varchar)
commercials_showrooms:
id (int) AI
commercial_id (int)
showroom_id (int)
And my models :
class Showroom extends AppModel
{
public $hasAndBelongsToMany = array(
'Commercial',
);
}
class Commercial extends AppModel
{
public $hasAndBelongsToMany = array(
'Showroom'
);
}
I'm trying to save data (hard coded for now) this way :
$this->loadModel('Showroom');
$this->Showroom->saveAll(array(
'Showroom' => array(
'id' => 1
),
'Commercial' => array(
'name' => 'test'
)
));
saveAll() returns (bool)true, however, nothing is saved in database.
How can I fix this ?
Did you read the section on "Saving Related Model Data (HABTM)" in the CakePHP book?
It suggests a different format than you're using for your data.
to test your table if is working try this in your controller:
$this->loadModel('CommercialsShowroom');
$CommercialsShowroom = array('CommercialsShowroom'=>array(
'commercial_id'=>your_value,
'showroom_id'=>your_value));
$this->CommercialsShowroom->create();
if ($this->CommercialsShowroom->save($CommercialsShowroom, false)){
var_dump('It is saved');
}
and for Model configuration read Dave link for more information
//CommercialsShowroom model:
var $belongsTo = array(
'Commercial' => array(
'className' => 'Commercial',
'foreignKey' => 'commercial_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Showroom' => array(
'className' => 'Showroom',
'foreignKey' => 'showroom_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
//Showroom model:
var $hasAndBelongsToMany = array(
'Commercial' => array(
'className' => 'Commercial',
'joinTable' => 'commercials_showrooms',
'foreignKey' => 'commercial_id',
'associationForeignKey' => 'showroom_id',
'unique' => true,
)
);
//Commercial model:
var $hasAndBelongsToMany = array(
'Showroom' => array(
'className' => 'Showroom',
'joinTable' => 'commercials_showrooms',
'foreignKey' => 'showroom_id',
'associationForeignKey' => 'commercial_id',
'unique' => true,
)
);
Is the following join structure correctly formatted to work with a CakePHP find? This doesn't seem to be working when I use it along with conditions and my gut tells me that the structure is off. I'm new to joins, so any help is appreciated.
'joins' => array(
(int) 0 => array(
'table' => 'cheeses_milk_sources',
'alias' => 'CheesesMilkSource',
'type' => 'INNER',
'conditions' => array(
(int) 0 => 'Cheese.id = CheesesMilkSource.cheese_id'
)
),
(int) 1 => array(
'table' => 'milk_sources',
'alias' => 'MilkSource',
'type' => 'INNER',
'conditions' => array(
(int) 0 => 'CheesesMilkSource.milk_source_id = MilkSource.id',
'CheesesMilkSource.milk_source_id' => '1'
)
)
),
'conditions' => array(
'AND' => array(
(int) 0 => array(
'Cheese.cheese_producer_id' => (int) 35
),
(int) 1 => array(
'Cheese.active' => (int) 1
)
)
),
The confusing part is
'conditions' => array(
(int) 0 => 'CheesesMilkSource.milk_source_id = MilkSource.id',
'CheesesMilkSource.milk_source_id' => '1'
)
You are mixing an array element without a key with one with a key equal to CheesesMilkSource.milk_source_id.
if you need to specify two conditions on the join, do it like
'conditions' => array(
'CheesesMilkSource.milk_source_id = MilkSource.id AND CheesesMilkSource.milk_source_id = 1'
)
perhaps the next snippet will equally work, but I'm not sure and can't test it at the moment - let me know if it does with a comment.
'conditions' => array(
'CheesesMilkSource.milk_source_id = MilkSource.id',
'CheesesMilkSource.milk_source_id = 1'
)
But since you're joining the tables, maybe you should put CheesesMilkSource.milk_source_id = 1 in the general conditions of the find:
'conditions' => array(
'Cheese.cheese_producer_id' => 35,
'Cheese.active' => 1,
'CheesesMilkSource.milk_source_id' => 1,
)
Notice you don't need to specify AND as this is the default way of joining conditions.