CakePHP - Saving an hasMany through association - cakephp

I'm currently trying to figure out how to save a hasMany through relationship.
My tables are:
cards:
id,
name
colors:
id,
name,
color
card_colors (associated with the model CardColor):
id,
card_id,
color_id,
cost
hasMany through Association:
Card hasMany CardColor
Color hasMany CardColor
CardColor belongsTo Card
CardColor belongsTo Color
In Card::beforeSave(), I'm going to reconstruct my $data variable so that it has this structure:
array(
'Card' => array(
'name' => 'theCard',
'CardColor' => array(
array(
'card_id' => 4,
'color_id' => 5,
'cost' => 2
),
array(
'card_id' => 5,
'color_id' => 2,
'cost' => 3
)
)
)
)
However, I don't know how to get the card_id for the card that I am currently inserting. Is there a more Cake-y way of saving a hasMany through association (such as getting the card id automatically in some way while saving)?

Try this:
Use $this->Card-create() // or just $this->create() in the model
In Card::beforeSave(), don't set the index CardColor[i][card_id]
Do the save this way: $this->saveAssociated($data)

Related

how to make associations between grand parent & parent & child in cakephp 2

I have 4 tabels
stores
categories
items
item_images
Now i want to make association between them categories have store_id foreign key and items table have category_id and item_images have item_id foreign key.
public $hasMany = array(
'Item' => array(
'className' => 'Item',
'foreignKey' => 'category_id'
));
The above association is for category that find the related items but i want to do associate it with item_images. How i can do it with item_images now?
In Controller i have this query
$storeCategoriesDetails = $this->Category->find("all", array('conditions' => array('Category.storeId' => $id)));
You want to put your association for the item_images on the Item model like you've done for items on the Category model. You can then retrieve the item images along with the items when retrieving categories using contain:-
$storeCategoriesDetails = $this->Category->find('all', array(
'contain' => array('Item' => array('ItemImage'))
'conditions' => array('Category.storeId' => $id)
));
I added this line in my controller function and it's working now.
$this->Category->Behaviors->load('Containable');

CakePHP Save data in HABTM Table

I am trying to save an array like this
$myData = array(
'User' => array('id' => 17),
'Group' => array(
array('group_id' => 2),
array('group_id' => 3),
array('group_id' => 4),
array('group_id' => 5),
array('group_id' => 6)
)
);
In my HABTM join table (groups_users). I tried the following save calls, but none of them worked.
$this->User->save($myData);
$this->User->saveAssociated($myData);
$this->User->saveAll($myData);
$this->User->GroupsUsers->save($myData);
$this->User->GroupsUsers->saveAll($myData);
Before you ask: Yes, my associations are set-up correctly and I was able to save data by calling:
$this->User->GroupsUsers->saveAll(array(
0 => array(
'GroupsUsers' => array('user_id' => $id, 'group_id' => 1)
),
1 => array(
'GroupsUsers' => array('user_id' => $id, 'group_id' => 2)
)
));
BUT only one of both records are saved, although I set unique to false in the model's HABTM relationship definition.
Where is the error? Is the structure of my array invalid?
The problem is that your data array is incorrectly formatted.
Your Group model will probably have an id field, and your join model GroupsUser will have a group_id field.
So you need to change your group_id to id
try
$myData = array(
'User' => array('id' => 17),
'Group' => array(
'Group' => array(
0 => 2,
1 => 3,
2 => 4,
3 => 5,
4 => 6
)
)
);
Just to answer your question even if it's old.
You doesn't have to call your 'GroupsUsers' model in your saveAll call, this is precisely the goal of associating Models, cakePHP does that for you.
You should pass this array to a saveAll function on your User/Group model:
array{
array{
'User' => array {
'id' => 25
},
'Group' => array {
'id' => 2
}
}
array{
'User' => array {
'id' => 47
},
'Group' => array {
'id' => 2
}
}
}
Both your User and Group Models should have and HABTM relation with each other, so that you just have to do that:
From the User/Group controller:
$this->User/Group->SaveAll($myData);
From the User/Group Model:
$this->SaveAll($myData);
And that's it, the GroupsUsers table will save 2 records, by saving by yourself in the HABTM relation table, you are not using the power of cakePHP.
And the records in both User and Group tables will be created if the ID doesn't exist, updated if not.
The only reason to save in an HABTM table is if you have some extra information you want to save in this table such as a 'validated' fields if you want to validate a member after he asked to join a group for example.

Associations not working properly in CakePHP

I have the following Models
Shop
_____________________________________
Id Name address city postalcode ...
Category
_______________________________________
Id Name Description shop_id ...
Product
______________________________________
Id Name Description category_id ...
And my Product Model I have defined $belongsTo relation like
public $belongsTo = array(
'Category' => array(
'className' => 'Category',
'conditions' => array('Category.shop_id' => 5)
)
);
What I need is that when I want to add New Product, in the Categories SelectBox should appear only Categories belonging to shop_id = 5 but I am getting all Categories.
Or i have to change the find method?
Yes, you need to add the conditions in the find query as you require it for add product
form.

CakePHP 2.1 - Saving (and creating) multiple Join Models and associated models

My model relationship is as follows:
Student hasMany ClassStudent
Class hasMany ClassStudent
ClassStudent belongsTo Student
ClassStudent belongsTo Class
ClassStudent is a join model.
What I want to do is create Student(s), use an existing Class or create a new one, and create a join model record that links the Students and classes.
I want to do this all in one call to save (if this is even possible).
I have tried:
$data = array(
'Student' => array(
'0' => array( ... ), // Data in here
'1' => array( ... ),
...,
'n' => array( ... )
),
'Class' => array(
'class_id' => x // The class that I want the above students to be associated with
)
)
What I want to do is create n records of students and also add them to a class (possibly creating a class at the same time if the users wants to add a new one). I also want to create a join model record for each Student to the Class when I am creating the Student records.
Is this possible? I am using Cake 2.1.0 (today's stable release), and I have tried the different types of saveAll (saveAssociated and saveMany) with $options['deep'] = true.
Is it possible my data array is not in the correct format?
EDIT:
I have also tried:
$data = array(
'ClassStudent' => array(
'0' => array(
'Student' => array (...), // Data
'Class' => array(id => x) // The id of the Class the Student should be associated to
...,
'n' => array(
'Student' => array(...), // n-th Student
'Class' => array(id => x)
)
);
$this->saveAll($data['ClassStudent'], array('deep' => true));
In the above case, it successfully creates new Student records in the students table, but nothing is created in the join table.
saveAll (saveAll is a wrapper to saveMany and saveAssociated) is the right tool for the job. Take a look at the documentation for saveAll, I don't see any notes about it changing for 2.1. Having taking more time to read, here are some thoughts
First off, is there a type in your array structure. You have
'Class' => array ( 'class_id' => x )
If the Class is already defined and you are just wanting to add a student, then it would be
'ClassStudent' => array( 'class_id' => x )
With that said, CakesPHP ORM should allow you to use a saveAll with on a hasMany using a numerical index, so if assuming you have a typo, there follow might work for you
$data = array(
'Student' => array(
'0' => array( ... ), // Data in here
'1' => array( ... ),
...,
'n' => array( ... )
),
'ClassStudent' => array(
'class_id' => x // The class that I want the above students to be associated with
)
)
$this->ClassStudent->saveAll($data);

Cakephp Relationships

I have a few models which are not in the default cakephp format
user(id, name....)
1 Harsha ...
2 John ....
dishes(id, name, price ...)
1 "Cheese Pizza" 6
2 "Zinger Burger" 3
restaurants (id, name, .....)
1 "KFC" ...
2 "Pizza Hut" ...
module(id, name) values (User, Dishes, Restaurants)
1 "Users"
2 "Dishes"
3 "Restaurant"
items (id, module_id, item_id)
1 1 1 (refers to User Harsha)
2 3 2 (refers to Pizza hut)
3 2 2 (refers to Zinger Burger)
4 1 2 (refers to User John)
where item_id refers to the Id of Users, Dishes or Rests Depending on the module_id
reviews (id, parent_id, review, time, item_id, commenter_id)
1 0 "Best Burger in the world" "time" 3 1 (refers to Harsha reviewing Zinger Burger)
2 1 "Yes i love Zingers tooo" time 3 2 ( refers to John replying to Harsha's Review)
I am a little messged up on how to draw up the relationships in cakephp
In the book at this page: http://book.cakephp.org/view/1039/Associations-Linking-Models-Together you'll find a guide to the possible keys you can set on the relationship, e.g.
foreignKey: the name of the foreign
key found in the other model. This is
especially handy if you need to define
multiple hasOne relationships. The
default value for this key is the
underscored, singular name of the
current model, suffixed with ‘_id’. In
the example above it would default to
'user_id'.
Assuming reviews and items are children in their associations, for both ends of the relationships, you'd set the foreignKey as 'item_id'.
Something like:
dishes:
class Dish extends AppModel {
var $name = 'Dish';
var $hasMany = array(
'Item' => array(
'className' => 'Item',
'foreignKey' => 'item_id',
...
items:
class Item extends AppModel {
var $name = 'Item';
var $belongsTo = array(
'Dish' => array(
'className' => 'Dish',
'foreignKey' => 'item_id',
...
),
'Restaurant' => array(
'className' => 'Restaurant',
'foreignKey' => 'item_id',
...
It's difficult to be more precise, but you haven't provided any datamodel. To handle the selection of Model via the Module, you'll need to write some code on a model somewhere, which one(s) depends on how you access the data.
However, it looks to me like a good time to restructure the database!

Resources