Use HABTM using transactions in empty Database CakePHP - php

I'm trying to store my data in an empty database using Transactions. Now this doesn't work for me. This is my ERD: https://www.dropbox.com/s/pfakd7xplsvr7cc/db_erd.PNG
Notice that at first all three tables are empty. And I send the following array to the database:
array(
'Product' => array(
'slug' => 'c24b626d6701d3b07e30b233b989ff8811',
'product_name' => 'DAHLIA 5A',
'price_new' => '159.00',
'affiliate_url' => 'http://example.com/feed.xml',
'product_id_supplier' => 'c24b626d670133d3b07e30b2b989ff8811',
'supplier_id' => 'some_supplier',
'feedimport_id' => (int) 1
),
'Image' => array(
(int) 0 => array(
'image' => 'product_image.JPG'
)
),
'Term' => array(
'Term' => array(
(int) 0 => array(
'name' => 'Tommy Hilfiger'
)
)
)
)
Using $this->getDataSource(); . But it only fills the images and products table. If I look at the log file, it appears it tries to select from the products_terms table, after inserting the products and images table, and ofcourse it receives nothing back. And there it stops.... It doesn't try to insert in the terms table either.
Now if I look at tutorials like these: http://www.pabloleanomartinet.com/cakephp-2-x-saving-and-validating-a-habtm-relation-example/
It looks like I don't do anything wrong... But if I look closely it looks like the TAGS table in the tutorial is filled already.... So probably that's the problem? But I don't know how to get a Term ID first, before inserting the product and linking them together, using transactions....
Anyone who does?

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.

Related

Filter query: Not null in elastic search

Currently I am working on Elastic Search 2.0 for my current Project. MySqL Query As follows,
select user_id from users where subscription_type ! = ''
In This above query, I Need to write in Elastic Search, I am trying in elastic search but it getting
please find below code in elastic search
$query = array("from" => $start,
"size" => $recordslimit,
"sort" => array(array('id' => 'desc')),
"query" => array(
"filtered" => array(
"query" => array("match_all" => array()),
"filter" => array("bool" => array(
'must_not' => array(
array('term' => array('subscription_type' => ''))
)))
)));
please help me out with this situation
I see two possible scenarios:
If subscription type is null or doesn't appear in your documents, then you can use missing query instead of a term query in the must_not clause.
On the other hand if you would like to exclude those documents whose subscription_type field holds the empty string, then your query is correct but maybe your mapping isn't. Make sure that subscription_type is defined as not_analyzed in the mapping.

Adding associated value by not using foreign key in CakePHP 2

Recently I've started using CakePHP by starting from using Bake to get simple CRUD.
I have one Model called "Contract" which is associated with "Product" and "Customer" as following.
public $belongsTo = array(
'Customer' => array(
'className' => 'Customer',
'foreignKey' => 'customer_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
Now I wanted to customize the add view (add.ctp) created by Bake by not using select box as an input form for customer_id and product_id. Instead of using select box which shows all the possible name of product/customer that are associated with foreign key I want to use text field so that people can type in one of the field (for example product_code, customer_code) from Product / Customer table and convert it to foreign key to create a row for Contract table. In case there is a chance that no values be found from Customer / Product field I want to skip adding a row to Contract table.
I would like to know if this is possible.
Thank you,
The basic concept is this: Use a JS lib of your choice, guess it's jquery. Watch the text field for changes, on change make an ajax GET request with the value of the text field to a controller / action of your app that returns json. On click on one of the results set the id of the selected record to a hidden field. Done.
If you search Google or Stackoverflow you'll find plenty of examples.

Complex ordering in CakePHP using Containable

I`m having a problem with the Containable behaviour.
I would like to know if there is any way to access the contained model attributes for operations like ordering.
For example, I have a model B which belongs to a Model A. I need to order objects of B using an attribute (integer) of A. It would be something like:
'contain' => array(
'A' => array(
'B' => array(
'order' => 'A.integer_attribute'
)
)
)
I know that there are easier ways to do this without Containable, but for reasons which are not worth being detailed here, I need to use it. This is an abstract example, in truth model A belongs to other models and this is just a small part of a deep containable tree.
I'd be very glad with any help!
EDIT
OK, I'll try my best to describe the situation without being unclear:
I have 4 models: User, Category, Field and UserField, and their relationships are as follows:
Category hasMany User
Category hasMany Field
User hasMany UserField
Field hasMany UserField
The opposite of these relations are all belongsTo. The purpose here is that the user belongs to a category, which has many fields that he needs to fill with his information (city, state etc). The information he fills is stored in the UserField table, as each information needs to have its field and the user who provided it.
That said, I need to build a screen which displays, for each category, a list of users and their information. So, I retrieve all the categories and its fields, so I can build a table for each category. Each field has an attribute "no_order", which is the number that indicates the order in which the field appears.
At the same time, I need all of each category's users to display them correctly in the tables. Finally, and there's the problem, I need to have UserField objects ordered by the "no_order" of their respective fields, for each user. So I ended up with something like:
$categories = $this->Category->find('all', array(
'order' => 'Category.name',
'contain' => array(
'Field',
'User' => array(
'UserField' => array(
'order' => 'Field.no_order'
)
)
)
));
But this doesn't work, since UserField cannot reach its respective Field's no_order from there.
I apologize if this wasn't clear enough, but for anyone who would spend a little while reading this, I would be VERY grateful for your help!
I am not shure for what do you want so, but I thing that should use joins of cakephp
$A = $this->A->find('all', array(
'joins' => array(
array(
'table' => 'B',
'alias' => 'B',
'type' => 'LEFT',
'conditions' => array(
'B.field_id = A.id'
)
)
),
'conditions' => array(
'B.field' => 'if_you_want_more_conditions'
),
'contain' => array(
'A' => array(
'B' => array(
'order' => 'A.integer_attribute'
)
)
),
'fields' => array('A.field','B.field'),
'recursive' => -1
));
I finally came up with a solution. I don't know how efficient it is, but there it goes:
'contain' => array(
'Field',
'User' => array(
'User.privilege = "Solicitante"'
'UserField' => array(
'order' => '(SELECT f.no_order FROM fields AS f WHERE UserField.field_id = f.id LIMIT 1)'
)
)
)
Having the raw query solved my problem. Hope it helps anybody who comes across a similar problem!

Saving HABTM data while also creating new record in related table with CakePHP

I'm building a site that works as a social network.
I have a profiles table and a Profile model.
Profile HABTM Interests
Profile HABTM Hobbies
etc...
There are a couple of pre-defined records in the hobbies and interests tables, which users can choose from to display on their profile. But they also have the option to add their own hobbies and interests if theirs isn't pre-defined.
A problem arises when the user chooses to add a hobby or interest which doesn't exist yet. Saving the pre-defined records to the join table is not a problem. But I can't seem to create new entries in the interests and hobbies tables during the same save call.
Below is a snippet of the data array I've tried to save (I've also tried other combinations, but this one seems the most logical):
array(
'Interests' => array(
'Interests' => array(
(int) 0 => '1',
(int) 1 => '2',
(int) 2 => '5'
),
'name' => 'Internet' //this is the user-created entry
),
'Hobbies' => array(
'Hobbies' => array(
(int) 0 => '1',
(int) 1 => '2',
(int) 2 => '5',
(int) 3 => '7',
(int) 4 => '8'
),
'name' => 'Reading' //this is also a user-created entry
)
)
The save function: $this->Profile->saveAll($this->request->data, array('deep' => true))
The problem is that the new entries (in this case "Reading" and "Internet") are being ignored during the save. There is no error and everything else is being saved just fine.
If I call $this->Profile->Hobby->saveAll($this->request->data) then it does work, but only for the Hobby model. The new interest is ignored of course, because the save call doesn't go through its model.
Is the data array not formatted correctly, or is this just not possible to achieve in one save call?
You might want to call saveAll using Profile, not Hobby.
$this->Profile->saveAll($this->request->data)

Removing Duplicate Code

I am working on a project and I just wanted to get some help on how to approach this problem and help clean up the code and remove a lot of duplication.
I have an FAQ database table with "id, user_id, faq_question, faq_text, sort_id". Now every time a dynamic site is created, I have an insert query which creates the site and then also inserts into the FAQ table with the default questions and answers that I want to use.
$insertFAQ = array(
'user_id' => $user_id,
'faq_question' => 'Default Question',
'faq_text' => 'Default Answer',
'sort_id' => '1'
);
$Db->insert('faq', $insertFAQ);
The sort_id is there because they have the ability to drag the questions in a different order and it updates the database and shows on the website in the new order.
Now the problem is that I want to have 10 default FAQ questions and answers that will be created for every website. If we get hundreds of sites in the database, that will be a ton of records in the FAQ database table which is pretty much all duplicated.
I know there has to be an easier way to do it, the only thing that throws me off is the sort_id because they could all have the same questions and answers but sort them differently. And then of course they have the ability to add custom questions.
P.S. - How can I add multiple questions/answers in the above array that I posted?
AS for having multiple question in the array you posted in the question, you can just have a multi dimensional array:
$insertFAQ = array(
0 =>array(
'user_id' => $user_id,
'faq_question' => 'Default Question',
'faq_text' => 'Default Answer',
'sort_id' => '1'
),
1 =>array(
'user_id' => $user_id,
'faq_question' => 'Default Question',
'faq_text' => 'Default Answer',
'sort_id' => '1'
),
2 => array(
'user_id' => $user_id,
'faq_question' => 'Default Question',
'faq_text' => 'Default Answer',
'sort_id' => '1'
) );`
and so on and son on.
as for the sorting -
You can create a separate table that will just hold the sorting order, site id and question id.
id, faq_id, site_id, sort_order
Id a new site is created you just create a new entry for it in this table, and than the questions don't have to repeat themselves, your only specifying what order goes to what site.
One way would be to have a site_id field in the table. For global faqs the site_id could be null.
Then to get the faqs for a site:
SELECT * FROM faq WHERE site_id IS NULL OR site_id = $site_id
If I understand correctly your question... To me it seems you simply need to split the question/answer from the user record, and have instead a reference to a question/answer entry in the user record:
// insert if it doesn't exist
$insertFAQ = array(
'faq_id' => $faq_id,
'faq_question' => 'Default Question',
'faq_text' => 'Default Answer'
);
// get faq id of newly inserted or existing faq entry
...
// insert user
$insertUser = array(
'user_id' => $user_id,
'faq_id' => $faq_id,
'sort_id' => '1'
);

Categories