CakePHP How can I save many records in a link table at once for user - map - attributes? - cakephp

I have three tables/models:
User(id)
Map(id, user_id, attribute_id)
Attribute (id, name)
Map belongsTo the others, the others hasMany Map.
I'd like the user (via user controller and user view) to create many links to associations at once. How can I do this, assuming that the user forms (add/edit) have 10 attribute fields, all linking to the same table?
I'd need to save up to 10 records in Map in one go. To start with, I'm unsure what the field should be - create('Attribute.name')? Also, cake outputs the same input name to each input as they point to the same field - what's the best way to fix this?
I have already read the relevant documentation, but didn't get much from it.
Thanks!

You can use saveAssociated() method. Prepare an input array according to the instructions given in the link and directly use $this->User->saveAssociated($your_array, array('deep' => true));

Related

Add content of form to 2 different tables cakephp

I am building a form with Cakephp 2.x and I want to submit some of the data that is received when submitting it to table A and the other data to table B. Does anyone know how to achieve this in cakephp?
I believe you need to look at Cakephp's model documentation. Looking at it now it seems that saveMany could help you with that. http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savemany-array-data-null-array-options-array
Yes. You should do what you want follow below way:
1. Create method receiveData() in FooController.
2. Create view file receive_data.ctp in folder foo.
$this->Foo->create();
$this->Foo->input('....', array(....));
// other input.
$this->Foo->end();
3. In FooController\receiveData(), When submit, you have data array $myDataArray like this: http://book.cakephp.org/2.0/en/tutorials-and-examples/blog/part-two.html#adding-posts
(Notice: It is Foo controller).
4. Before you save data from submitted data, you maybe need manipulation with submitted data array.
5.
You must call Model Bar inside FooController by:
$uses = array('Bar');
You will save to other table by:
$this->Bar->save($myDataArray);
(Notice: It is Bar Model).
Do Table A and Table B represent two different Models?
if yes saveAssociated might help you.
http://book.cakephp.org/2.0/en/models/saving-your-data.html#saving-related-model-data-hasone-hasmany-belongsto
If you want to save the same kind of model n times then saveMany is what you want to do.

Cakephp - Load a view from another view in a different controller

I've been trying for the past 2 days, how to embed a view from a different controller.
I have two tables (hotels, hotelQuotes), related to each other. The hotels table is linked with a hasmany to the hotelQuotes table, and hotelQuotes with a belongsTo hotels table. Both are linked and working, they both show their related content with no problem.
The hotelQuotes it's pretty much a form, where users fill it out, and then it sends an Email with what the user filled out. Everything is working fine up to this point.
What I want is, when I show the information about the hotel, is to also show that form, I dont want the user to go to another page to fill out the form. So I pretty much want to embed the view of hotelQuotes/Add to the hotel/view.
I doing that using elements, as recommended last night in #cakephp IRC channel, and also here in StackOverFlow at: Embedding view in another view with CakePHP
The problem is that when I do that, the association between the two models gets broken. I mean, the users fill out the form, but I have nowhere to know where that form is coming from, what hotel is referring to. It just doesn't show that piece of vital information for me.
I've been reading about passing variables when using elements at: http://book.cakephp.org/2.0/en/views.html#passing-variables-into-an-element but I don't know how to pass a variable to a form select box. I am using CakePHP 2.5.2.
I hope I explain myself clear here, any input it would be appreciated. See picture below for more info:
http://i.stack.imgur.com/wcG64.jpg
Edit> I just realized that the form is not even submitting when I using elements. Why would that be?
Ok, I just figured out.
The form wasn't even submitting when calling it from elements. So I just passed the action myself like so:
echo $this->Form->create('Hotelquote', array(
'action' => 'add'
));
And now is working.

checkboxes for table records

I want to let user to publish or unpublish some articles at once. So, in articles list view, I want to put a checkbox beside each row (article) and send these checkboxes to controller.
I tried to use $this->Form->input('status') after each row in my loop, but it created same checkbox for each article. (inputs name and id are the same)
How to create an array of checkboxes or something like this? And how to check them in controller?
Note: Each article has a status field, which is a tinyint 1 character field. (so Cake can understand it's a checkbox)
You will need to specify an 'index' for each input.
In stead of this:
$this->Form->input('Article.status');
Use this:
$this->Form->input('Article.0.id');
$this->Form->input('Article.0.status');
$this->Form->input('Article.1.id');
$this->Form->input('Article.1.status');
// ....
$this->Form->input('Article.xxx.id');
$this->Form->input('Article.xxx.status');
It's the 'index' is just a counter to make sure that 'unique' inputs are generated. However, it is important that each row contains an input for the id of that row; CakePHP will need that to determin which record it should update the status for.
Further reading
Documentation on the naming of fields/inputs can be found here:
FormHelper field naming conventions
CakePHP - Create a form which edits multiple rows of the same model

CakePHP - Prevent model data being save in a saveMany call when certain fields are blank

I have scenario where I have 3 different models data being saved from one form, by means of the saveAll pass through method in CakePHP 2.x
The models on the form are:
Project
ProjectImage
ProjectAttachment
1 and 2 are saving perfectly, but I am having problems with the ProjectAttachment fields. If you look at the following image, the fields in question are at the bottom right, highlighted by a red frame: http://img.skitch.com/20120417-bnarwihc9mqm1b49cjy2bp13cf.jpg
Here is the situation:
I have named the fields as follows: *ProjectAttachment.0.project_id*, ProjectAttachment.0.name .... *ProjectAttachment.6.project_id* etc where the numbers are relative to the already present amount of attachments the user has added, as there is no limit. So if the user has ALREADY added 6 documents, the field would be called ProjectAttachment.7.id and so on. This is because of the naming convention when using the saveAll method.
I have made use of two hidden fields, one to store the user ID, the other to store the project ID.
The problem is that if the user does not fill in the Document Title and select a file to upload, the form fails! If I remove all validation rules, the form no longer fails BUT a blank ProjectAttachment record is inserted.
I suspect the problem may also be that the project_id and user_id fields (that are hidden) already have values in them?
I gave it some thought, and came up with a simple concept: In my controller, before the saveAll call, I would check to see if a blank Document Title field was submitted, and if so, I would completely eliminate the relevant array entry from the $this->request->data['ProjectAttachment'] array, but this did not seem to work.
To clarify, I am not looking for validation rules. If the user decides they only want to upload images and not touch the ProjectAttachment form, them the saveAll operation must not fail, it must simple not attempt to save the blank fields in the form, if this is at all possible.
Any suggestions?
Kind regards,
Simon
Well it seems that the solution was far simpler than I had initially thought! I was partially on the right track, and I had to unset the variable ProjectArray key in the $this->request->data array if I had encountered any blank fields.
I did this as follows:
if(!empty($this->request->data['ProjectAttachment'])){
foreach($this->request->data['ProjectAttachment'] as $key => $value){
if(is_array($value) && array_key_exists('upload_file', $value)){
if($value['upload_file']['name'] == ''){ // Blank document file
unset($this->request->data['ProjectAttachment']);
}
}
}
}
I hope someone finds this somehow useful in some form or another.
Kind regards,
Simon

cakephp habtm relationships with input rather than select box?

I'm creating a form in cakephp that has a typical HABTM relationship. Let's say that I'm developing an order form with a coupon code. From a logic point of view, I need to accept a text-entry for the coupon code, so the incoming data would not be the proper primary key, but rather a different field.
I would then need to validate that data, and retrieve the proper primary key id, and then update the orders_coupons table with that coupon_id, and order_id.
When using a select box the value would always be the proper coupon_id, but where is the appropriate location for me to put the logic to handle this? Should I modify the data using beforeSave?
your question isn't very clear b/c it sounds like you can both specify the coupon via a select box or in just a free form text box.
My inclination is to add a new method to the Model that would update the record with the "human readable key". So the function would first read the coupon_id from the DB, and then do the update.
As you said, you'll just have to look up the coupon id...
// assuming $data looks like:
// array('Order' => array(...), 'Coupon' => array('code' => ...))
$coupon_id = $this->Order->Coupon->field('id', array('code' => $data['Coupon']['code']));
if (!$coupon_id) {
// user put in a non-existing coupon code, punish him!
} else {
$data['Order']['coupon_id'] = $coupon_id;
$this->Order->save($data);
}
If I get this correct, this is pretty much the same as tagging?! (There is a text input box for habtm items and the string is submitted to the controller without the ids).
If so, I would recommend to split the processing. Submit the data to the controller and then pass the coupon-string to a proper function in the coupon-model, that gets the coupon-ids (saves new items) and returns them back to the controller to save the complete habtm-data.

Resources