cakephp assocations issue in 2x - php

I have two tables
messages
users
users has roles Doctor and user.
messages has doc_id & user_id.
How do I make an association, so that it returns me both data doc_id & user_id from users.

For the Role association on User you will need a join table, thats if i am right in believing a User can have many roles?
You'r Message model should only have a BelongsTo User, then when your doing loop ups you will use deep associations in your find methods to bring back some like...
// Find with deep assosiations
$this->Message->find('all', array());
Array
(
[Message] => Array
(
[id] => 2
[body] => example body...
)
[User] => Array
(
[username] => John
[Role] => Array
(
[0] => 2
[1] => 6
)
)
)

class Message extends AppModel {
public $hasMany=array('MessageDetail');
public $belongsTo = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_id',
),
'Doctor'=>array(
'className'=>'User',
'foreignKey'=>'doc_id'
),
'Petprofiles'=>array(
'className'=>'PetProfiles',
'foreignKey'=>'petprofiles_id'
)
);
}

Related

CakePHP Relational models: Completely ignoring model

I have a pretty simple relational model setup. When using $this->model->find('all',$params), the results do not return the complete relational data set. I'm pulling my hair out here.
Here's my table setup:
Table qs_skus:
id (AI, PK)
sku_name
profile
...
Table net_lengths_in_skus:
id (AI,PK)
quick_ship_skus_id
net_lengths_id
Table net_lengths
id (AI,PK)
name
The way the models are configured are:
Model QuickShipSku $hasMany=array('NetLengthsInSku')
Model NetLengthsInSku $hasOne='NetLength'
All models have $actAs = array('Containable')
When doing the following, I get only the first relationship queried, the last relationship is completely ignored:
$model = $this->QuickShipSku->find('all',
array(
'contain' => array(
'NetLengthsInSku' => array('NetLength')
)
);
Output:
Array
(
[0] => Array
(
[QuickShipSku] => Array
(
[id] => 3
[sku_name] => 1112-8
[product_name] => Product A
[sku_specie_id] => 1
[members_ft] => 8
[profile] => Profile Description
)
[NetLengthsInSku] => Array
(
[0] => Array
(
[id] => 10
[quick_ship_skus_id] => 3
[quick_ship_net_length_id] => 1
)
)
)
)
For each NetLengthsInSku there should be a NetLength, but it's not even being queried.
Any ideas?
What you have here is a many to many relationship. That means an association called hasAndBelongsToMany.
If you are using Cake 2.x you should have something like this:
class QsSku extends AppModel {
public $hasAndBelongsToMany = array(
'NetLength' =>
array(
'className' => 'NetLength',
'joinTable' => 'net_lengths_in_skus',
'foreignKey' => 'quick_ship_skus_id',
'associationForeignKey' => 'net_lengths_id',
)
);
}
You should do something similar to your NetLength model as well.

Adding Join from another Model using Button (CakePHP)

I have a Course model and a User model joined by Subscription. I want to create a postLink form helper on the Courses index page that would automatically subscribe the user to that, but I don't know how to pass the parameters correctly. In essence, I want the user to click Subscribe, and have a subscriptions/add form automatically submitted so that the join table has another record.
My specific question is: How do I use a model in another model's view?
Here's the Courses index.ctp array from print_r:
Array
(
[0] => Array
(
[Course] => Array
(
[id] => 1
[name] => Flying
[created] => 2014-01-27 19:05:43
[modified] => 2014-01-27 19:05:43
)
[Subscription] => Array
(
[0] => Array
(
[id] => 2
[user_id] => 2
[course_id] => 1
)
)
)
)
Here's my bad postLink in the Course index.ctp view:
<?php
echo $this->Form->postLink(__('Subscribe'),
array( 'controller' => 'Subscriptions',
'action' => 'add' ),
null,
__('Are you sure you want to subscribe to # %s?',
$course['Course']['name']));
?>
Assuming they're associated, you can do like you would in the Controller - just don't include the model you're actually in, since $this is already that model:
$this->AssociatedModel->save($data);

CakePHP hasMany through (the join model) not saving

I have a hasMany through (the join model) which is not saving, but when reading, it works naturally.
I will try to provide as much detail as possible, so bear with me. Please note I am trying to save a new user paired with quantities of existing products, and I am not wanting to add new products in this save.
Database Tables: users, products, subscribed_users
Table structure of joining table: id, user_id, product_id, quantity, created, modified
User.php
public $hasMany = array(
'SubscribedUser'
);
Product.php
public $hasMany = array(
'SubscribedUser'
);
SubscribedUser.php
class SubscribedUser extends AppModel {
public $belongsTo = array(
'User', 'Product'
);
}
Data array I am trying to save from within the UsersController.php
Array (
[User] => Array (
[username] => asdf
)
[SubscribedUser] => Array (
[0] => Array (
[product_id] => 50f1ef25-6884-44cf-80e4-bd346f01a4c2
[count] => 12
)
[1] => Array (
[product_id] => 50f1f1d6-89b4-4ade-961f-c1a06f01a4c2
[count] => 12
)
)
)
Using $this->User->SubscribedUser->saveAll($data); I have the User properly saved, but my subscribed_users table only has one row (as you can see from my above data, there should be two) and it contains missing data. There is no product_id, and the count number is 0.
I am not sure what I am missing here. Thoughts?
Unless it's a typo the filename Users.php is the most obvious error.
The problem was I was using $this->User->SubscribedUser->saveAll() and not $this->User->saveAll()
My problem is now solved with this resolution.

CodeIgniter Join Fields Help?

I need help constructing a CodeIgniter Datamapper ORM query that includes join fields.
I have a table of Merchants and a table of Vendors.
They have a many-to-one relationship, that is, many Merchants are part of a single Vendor.
Thus, my datebase tables, following the Datamapper ORM convention are:
merchants
vendors
merchants_vendors
Furthermore, in the merchants_vendors table, I have join fields 'role' and 'admin'.
Obviously, this data must be placed in the join table, if it were placed in the Merchants table, I wouldn't be able to define roles and administrators per Vendor.
Lastly, Merchants are related to Users by a one-to-one relationship.
Think of Merchants as just an extension of Users.
I'm attempting to create a PHP array from the data that follows this data structure, but I can't seem to get the role and admin fields populating properly. I removed redundant columns for your simplicity:
[vendor] => Array
(
[id] => 1
[name] => Vendor1
[users] => Array
(
[0] => Array
(
[id] => 277
[username] => merchant1
[firstname] => Merchant1
[merchant] => Array
(
[id] => 1
[user_id] => 277
[role] => Sales
[admin] => 0
)
)
[1] => Array
(
[id] => 282
[username] => merchant2
[firstname] => Merchant2
[merchant] => Array
(
[id] => 2
[user_id] => 282
[role] => Software
[admin] => 1
)
)
)
)
Here's the code I'm using - Assuming we know the Vendor ID:
$v = new Vendor($id);
if($v->exists())
{
$d['vendor'] = $v->to_array();
$m = new Merchant();
$m->where_related_vendor('id', $v->id)->get();
if($m->exists())
{
foreach($m as $mK => $mV)
{
$u = new User();
$u->where_related_merchant('id', $mV->id)->get();
$d['vendor']['users'][$mK] = $u->to_array();
$d['vendor']['users'][$mK]['merchant'] = $mV->to_array();
}
}
}
$this->load->view('myview', $d);
This gets me as far as the above PHP data structure without the role and admin.
I am well aware of the include_join_fields() function - but I cannot seem to get it working. Specifically, I tried $m->vendor->include_join_fields(); Then tried to access the role/admin fields by $mV->vendor->join_role and $mV->vendor->join_admin - but that doesn't work.
Your help is much appreciated!
The solution was to use include_join_fields() on the $mV object inside the forloop:
$v = new Vendor($id);
if($v->exists())
{
$d['vendor'] = $v->to_array();
$m = new Merchant();
$m->where_related_vendor('id', $v->id)->get();
if($m->exists())
{
foreach($m as $mK => $mV)
{
$u = new User();
$u->where_related_merchant('id', $mV->id)->get();
$mV->vendor->where('id', $v->id)->include_join_fields();
$d['vendor']['users'][$mK] = $u->to_array();
$d['vendor']['users'][$mK]['merchant'] = $mV->to_array();
$d['vendor']['users'][$mK]['merchant']['role'] = $mV->vendor->join_role;
$d['vendor']['users'][$mK]['merchant']['admin'] = $mV->vendor->join_admin;
}
}
}
$this->load->view('myview', $d);
Ongoing discussion in the CodeIgniter forums.
I will post more information as it arrives.
include_join_fields() doesn't execute anything, it just sets a flag that you want these fields included.
Both examples above miss the get() that actually executes the query...

Name of associative model in CakePHP

At first sorry for my English.
I've got a problem in associative models in CakePHP. When I bind more than two models, for example
$this->Album->bindModel(
array(
'hasMany'=>array(
'Photo'=>array(
'className'=>'Photo'
),
'Album'=>array(
'className'=>'Album'
)
)
)
);
I have:
Array
(
[Album] => Array
(
[id] => 22
[f_name] => Some album
[0] => Array
(
[id] => 19
[f_name] => Another album
[id_parent] => 22
[Photo] => Array
(
....
Is it any way to set a key in parent table? I mean I don't want to have "0" as a key, there can be "Album1", "Album2" and so on.
The problem likely stems from binding a model to itself under the same name. Album hasMany Album probably trips up Cake somewhere. Use a unique name for the association, like Album hasMany SubAlbum.

Categories