Each Artikel has exactly one Barcode. For several reasons I want to split the Artikel model and the Barcode model. When I find() something from the artikel table it returns an array which contains the correct barcode section. But when I try to find a barcode, the array's artikel section is nulled.
This is what I mean:
// $this->Artikel->findById(102);
array(
'Artikel' => array(
'id' => '102',
'name' => 'Spätburgunder Spätlese Barrique',
'erzeuger_id' => '679',
'volumen_id' => '44',
'artikelgruppe_id' => '17'
),
'Barcode' => array(
'id' => '1',
'artikel_id' => '102',
'barcode' => '123456'
)
)
// $this->Barcode->findByBarcode(123456);
array(
'Barcode' => array(
'id' => '1',
'artikelnummer' => 'DE51076',
'barcode' => '123456'
),
'Artikel' => array(
'artikelnummer' => null, // this is null
'name' => null, // this is null as well
'erzeuger_id' => null, // also null
'volumen_id' => null, // ……
'artikelgruppe_id' => null // null
)
)
Any ideas what I did wrong?
These are the models
// Barcode.php
public $hasOne = array(
'Artikel' => array(
'className' => 'Artikel',
'foreignKey' => 'artikel_id'
)
);
// Artikel.php
public $hasOne = array(
'Barcode' => array(
'className' => 'Barcode',
'foreignKey' => 'artikel_id'
)
);
Article table - id, name, artikelgruppe_id and Barcode table - id, artikel_id, barcode
The correct way to relate these models is: Article hasOne Barcode and Barcode belongsTo Article
// Artikel.php
public $hasOne = array(
'Barcode' => array(
'className' => 'Barcode',
'foreignKey' => 'artikel_id'
)
);
// Barcode.php
public $belongsTo = array(
'Artikel' => array(
'className' => 'Artikel',
'foreignKey' => 'artikel_id'
)
);
Here article_id is in the Barcode table, so Article hasOne Barcode works as expected. Barcode hasOne Article would have worked if you had a barcode_id in your Article table.
But since you need the article from article_id field in Barcode table, you should use belongsTo relationship.
From what controller are you making those callings? If you are on the same model then is wrong because you must do the call through the references between the models. For example, I asume that you are in the Artikel model, so your first call is right, but the second one should be $this->Artikel->Barcode->findById(1)
Related
I am trying something more complicated. I have an Item which stores all general items, I have a Product which is an item and I have a Good which is a product and a item. So I have a form for entering value for the good and it shall save to all model related tables (items, products, goods). The reason for so many tables is because all tables shall have an id which is used later, example: product shall have its id which is used later for selling. Here is the controller:
public function add() {
$this->load();
if ($this->request->is('post')) {
$this->Item->create();
$this->request->data['Item']['code'] = $finalCode;
$this->request->data['Item']['is_deleted'] = false;
$item = $this->Item->save($this->request->data);
if(!empty($item)){
$this->request->data['Product']['item_id'] = $this->Item->id;
$this->request->data['Good']['item_id'] = $this->Item->id;
debug($this->request->data['Product']['item_id']);
debug($item);
$this->Item->Product->save($this->request->data);
$this->request->data['Good']['pid'] = $this->Product->id;
$this->Item->Good->save($this->request->data);
}
if($this->Good->validationErrors || $this->Item->validationErrors || $this->Product->validationErrors){
//ERRORS
}
else{
//FAILS
}
}
}
EDIT: I have changed the controller and now the Item is never saved but Product and Good is saved and they are all mapped well, ids are ok but Item is not even in the db, althrough Product and Good have item_id set to a value which should be next in the db.
class Good extends AppModel {
public $belongsTo = array(
'Item' => array(
'className' => 'Item',
'foreignKey' => 'item_id',
),
'Product' => array(
'className' => 'Product',
'foreignKey' => 'pid',
)
);
}
class Product extends AppModel {
public $hasOne = array(
'Good' => array(
'className' => 'Good',
'foreignKey' => 'pid',
'dependent' => false,
),
);
}
class Item extends AppModel{
public $hasMany = array(
'Good' => array(
'className' => 'Good',
'foreignKey' => 'item_id',
'dependent' => false,
),
'Product' => array(
'className' => 'Product',
'foreignKey' => 'item_id',
'dependent' => false,
),
);
}
Even the debugged $item looks ok but is not saved:
array(
'Item' => array(
'name' => 'Microcontrollers',
'description' => 'Wire Jumpers Female-to-Female 30 cm',
'weight' => '22',
'measurement_unit_id' => '7',
'item_type_id' => '29',
'code' => 'GOD-34',
'is_deleted' => false,
'modified' => '2019-10-22 12:37:53',
'created' => '2019-10-22 12:37:53',
'id' => '120'
),
'Good' => array(
'status' => 'development',
'hts_number' => '8473 30 20',
'tax_group' => '20%',
'eccn' => 'EAR99',
'release_date' => array(
'month' => '10',
'day' => '22',
'year' => '2019',
'hour' => '10',
'min' => '10',
'meridian' => 'am'
),
'is_for_distributors' => '1'
),
'Product' => array(
'project' => 'neqwww'
)
)
I think the problem is with your code at the lines where you are saving the data.
$this->Item->create();
$this->Good->create();
$this->Product->create();
What is $this? If you create a item with "$this" and later try to create a "product", "$this" will not have the item_id.
Try using something like this to save the item created.
$item = $this->Item->create();
Then, with that $item created, you could create a $product with the $item->id
Update:
From cakephp documentation.
// Create: id isn't set or is null
$this->Recipe->create();
$this->Recipe->save($this->request->data);
// Update: id is set to a numerical value
$this->Recipe->id = 2;
$this->Recipe->save($this->request->data);
You must use $this->Item->save($data) to save the information into database.
https://book.cakephp.org/2.0/en/models/saving-your-data.html
Maybe the method create() is a bit unclear. It is used to restart the model state.
So, it would be
$item_saved = $this->Item->save($data['Item']);
$data['Product']['item_id'] = $this->Item->getLastInsertId();
$product_saved = $this->Product->save($data['Product']);
Edit 2:
Maybe it is because you didn't use create() before save the Item. Try this please:
$this->Item->create();
$item_saved = $this->Item->save($data['Item']);
$data['Product']['item_id'] = $this->Item->getLastInsertId();
$product_saved = $this->Product->save($data['Product']);
I am having problems with the CakePHP belongsTo and hasAndBelongsToMany relationships in CakePHP 2.x
Example situation
Table users
id
organisation_id
Table organisations
id
name
Table user_organisation_permissions
id
user_id
organisation_id
UserModel
hasAndBelongsToMany(Organisation);
belongsTo(Organisation)
A user belongs to one organisation but it has permissions on multiple organisations, resulting in the following conflict:
$aUser = $this->User->findById(1);
print_r($aUser);
// Output
# With the belongsTo relation
array(
'User' => array(
'id' => 1,
'organisation_id' => 1
'name' => 'Test User'
),
'Organisation' => array(
'id' => 1,
'name' => 'Test organisation'
)
);
# With the hasAndBelongsToMany relation
array(
'User' => array(
'id' => 1,
'organisation_id' => 1
'name' => 'Test User'
),
'Organisation' => array(
1 => array(
'id' => 1,
'name' => 'Test organisation'
),
2 => array(
'id' => 1,
'name' => 'Test organisation'
)
)
);
# When both relations are enabled it doesn't work
Does anybody have a solution for this conflict?
Is there a "native" CakePHP solution for this conflict?
The answer is actually in the CakePHP 2.x Cookbook.
Multiple relations to the same model
There are cases where a Model has more than one relation to another Model. For example, you might have a Message model that has two relations to the User model: one relation to the user who sends a message, and a second to the user who receives the message. The messages table will have a field user_id, but also a field recipient_id. Now your Message model can look something like:
class Message extends AppModel {
public $belongsTo = array(
'Sender' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Recipient' => array(
'className' => 'User',
'foreignKey' => 'recipient_id'
)
);
}
Source: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#multiple-relations-to-the-same-model
In kid model i have defined this below HABTM relation.
public $hasAndBelongsToMany = array(
'Pics' => array(
'className' => 'Pic',
'joinTable' => 'pics_kids',
'foreignKey' => 'kid_id',
'associationForeignKey' => 'pic_id'
)
);
Pics table store details of pics like comment, pic_url and date and pics_kids table have pic_id and kid_id id's that relate pic and kids . If i have to retrieve record based on kid_id and date(date of pic in pics table) how to retrieve it?
$kid_pics=$this->kid->find('all', array(
'conditions' => array(
'kid.id' => 1,
'Pic.date' => '26/07/2014'
)
));
if i use above query i get error that no column Pic.date in where claue.
Add a condition to your HATBM relationship dynamically:
$this->Kid->hasAndBelongsToMany['Pic']['conditions'] = array(
'Pic.date' => '26/07/2014'
) ;
$kid_pics = $this->Kid->real(null, 1) ;
You can use built-in Containable Behavior
$this->Kid->Behaviors->load('Containable');
$kid_pics = $this->Kid->find('all', array(
'conditions' => array(
'Kid.id' => 1
),
'contain' => array(
'Pic' => array(
'conditions' => array(
'Pic.date' => '26/07/2014'
)
)
)
));
I am trying to display a field from a 3rd table in a relationship, and after checking posts here and the docs, I am still stuck.I have 3 models all related in some way. I have found similar posts here but I am still not getting it to work. I am learning so sorry if I have missed this somewhere in the docs but I have read a fair bit and have tried a lot. I am guessing too much now on this so I need help.
1)Tutorsession - belongsto teachers,
2) Teacher -has 1 user,hasmany tutorsessions
3) User- has 1 teacher, //////I want to display a field from this table given I display tutorsessions
In controller
$this->set('tutor',
$this->Tutorsession->find('first',
array(
'conditions' => array('Teacher.user_id' => $id),
'contain' => 'User.username'
)
)
); //////////no error but no results
from view echo '<td>'. $item['User']['username'].'</td>'; ///////error user undefined
The tutorsession automatically gets rows from teacher table but not user table witht he model setup on a findall.
I want to display a username from the user table. I display the tutorsession table , I then can display the teacher table with the model association but I cant go from the teacher table to the user table to get a user name from the user id as the common field. I have checked the docs below and I am not sure why my code isnt ble to display a username from users table.
http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
update: here are the models
class User extends AppModel {
public $hasOne = array(
'Teacher' => array(
'className' => 'Teacher',
'dependent' => true
)
class Tutorsession extends AppModel
{
public $name='Tutorsession';
public $belongsTo = array(
'Teacher' => array(
'className' => 'Teacher',
'foreignKey' => 'teacher_id'
)
class Teacher extends AppModel
{
public $name='Teacher';
public $hasMany = array('Tutorsession');
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
Add containable behavior in your Model
public $actsAs = array('Containable');
Execute following query In controller
$contain = array('Teacher' => array('User'));
$this->set('tutor', $this->Tutorsession->find('first',array(
'conditions' => array('Teacher.user_id' => $id),
'contain' => $contain
)));
Try this:
$this->Tutorsession->recursive = 2;
$this->Tutorsession->Teacher->contain('User');
$this->set('tutor',
$this->Tutorsession->find('first',
array(
'conditions' => array('Teacher.user_id' => $id)
)
)
);
$tutor=$this->Teacher->find('first',
array(
'conditions' => array('Teacher.user_id' => $id)
)
);
debug($tutor); exit();
Your result similar:
'Teacher' => array(
'id' => '1',
'name' => 'abc',
'created' => '1397040385',
'updated' => '1397725860'
),
'User' => array(
'id' => '4',
'name' => 'administrators',
'created' => '1397032953',
'modified' => '1397032953'
),
'Tutorsession' => array(
0=>array(
'id' => '3',
'name'=>'abc',
'created' => '1400729137'
),
1=>array(
'id' => '4',
'name'=>'abc',
'created' => '1400729137'
)
)
Ensure your models are correct
I'm trying to import products from a productfeed and save them into my database. Now I'm having trouble to get this done with cakePHP. It's quite easy to fill the "products" table, but hard to fill the "terms" and joining table "products_terms". I'm using transactions ($dataSource = $this->Supplier->Product->getDataSource();) to import the products, to be sure no incomplete data will be saved into the database. Now cause the terms table uses AutoIncrement for the term id's, it's hard for me to fill the products_terms table cause it's only possible after I know the id of the term. If the ID doesn't exist yet, I cannot know what to fill in the products_terms table. See my ERD below
https://www.dropbox.com/s/pfakd7xplsvr7cc/db_erd.PNG
Does anyone know a solution for this?
Array I send to the database
array(
'Product' => array(
'slug' => 'c24b626d6701d3b07e30b233b989ff8811',
'product_name' => 'DAHLIA 5A',
'price_new' => '159.00',
'affiliate_url' => 'http://ad.zanox.com/ppc/?utm_source=zanox&utm_medium=banner&utm_campaign=product]]',
'product_id_supplier' => 'c24b626d670133d3b07e30b2b989ff8811',
'supplier_id' => 'zizigo_tr',
'feedimport_id' => (int) 1
),
'Image' => array(
(int) 0 => array(
'image' => 'zizigo_tr_5290e6d296084.JPG'
)
),
'Term' => array(
'Term' => array(
(int) 0 => array(
'name' => 'Tommy Hilfiger'
)
)
)
)
And my models:
class Product extends AppModel {
public $name = 'Product';
public $primaryKey = 'product_id';
public $hasMany = array(
'Vote',
'Image'
);
public $hasAndBelongsToMany = array(
'Term' => array(
'className' => 'Term',
'joinTable' => 'products_terms',
'foreignKey' => 'product_id',
'associationForeignKey' => 'term_id',
'unique' => true
)
);
public $belongsTo = array(
'Supplier'
);
}
class Term extends AppModel {
public $name = 'Term';
public $primaryKey = 'term_id';
public $hasAndBelongsToMany = array(
'Product' => array(
'className' => 'Product',
'joinTable' => 'products_terms',
'foreignKey' => 'term_id',
'associationForeignKey' => 'product_id',
'unique' => true
)
);
}
Problem solved. It seems like the Terms table needs to be filled, else cakePHP doesn't know which term to connect to.
So the proper solution is to first check or the Term exists, else insert the Term in the Terms table, and then insert the products using HABTM (using the ID of the Term in the insert array), so the products_terms table will be filled also.