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