I have to contain two models with json field value in cakphp - cakephp

log table with product id
product table
My Log tables contained data field having json data like
{"product-id":"14","product-name":"test","product-url":"\/projects\/test\/products\/lecture-details\/8","product-type":"lecture","product-price":"0"}
I want to join products table with the product id stored in data file.How can I do that?
log table "product-id": "14" this field need to be contained with product table.
$getQuery = $this->Log->find('all')->matching('Users', function ($q) { return $q->where(['Users.is_deleted' => 'n']);})->contain(['Users','Products'])->select(['user_id' => 'Users.id', 'username' => 'Users.username','fname' => 'Users.fname','lname' => 'Users.lname', 'email' => 'Users.email','view_date' => 'Log.dt_created_on','data' => 'Log.data'])->where($conditions);

Add this code Log association model
$this->hasOne('Products', [
'className' => 'Products',
'foreignKey' =>false,
'conditions' => array("Products.id=JSON_VALUE(cast(log.data as nvarchar(256)),'$.\"product-id\"')")
]);

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 3 : How to fetch joing table associated data?

I have a table name countries , countries has relation with users, users has relation with MoneyTransferTransactions
In MoneyTransferTransactions view I need fetch country name.
I already join Users table in MoneyTransferTransactionsTable by below code
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
In user table I also used inner join like below code
$this->belongsTo('Countries', [
'foreignKey' => 'country_id',
'joinType' => 'INNER'
]);
In MoneyTransferTransactions controller I have used below code to fetch all data with associated data.
$this->paginate = [
'contain' => ['Users','TransferOptions'],
'conditions'=> ['MoneyTransferTransactions.status'=>1],
'order' =>['MoneyTransferTransactions.id'=>'DESC']
];
I have used var_dump in index.ctp , I gotted country id from users table but not got country name from countries table. How can I get country name from MoneyTransferTransactions>index.ctp ?
Add association between Users and Countries in 'contain'
$this->paginate = [
'contain' => ['TransferOptions', 'Users' => ['Countries']],
'conditions' => ['MoneyTransferTransactions.status' => 1],
'order' => ['MoneyTransferTransactions.id' => 'DESC']
];

CakePHP 3 Sort by associated model with HasOne relationship

Order HasOne Suborder
Suborder BelongsTo Order
I need to sort Orders by a field in Suborders, but sorting by virtual fields appears to have been removed in Cake 3.x
In OrdersTable.php, I have
$this->hasOne('Suborder', [
'className' => 'Suborders',
'foreignKey' => 'order_id',
'strategy' => 'select',
'conditions' => function ($exp, $query) {
return $exp->add(['Suborder.id' => $query
->connection()
->newQuery()
->select(['SSO.id'])
->from(['SSO' => 'suborders'])
->where([
'Suborder.order_id = SSO.order_id',
'SSO.suborder_type_id in' => [1, 2, 3]
])
->order(['SSO.id' => 'DESC'])
->limit(1)]);
}
]);
In OrdersController.php, I have
$this->paginate = [
'limit' => 20,
'order' => ['id' => 'desc'],
'sortWhitelist' => [
'id',
'title',
'client_order',
'substatus',
'Workflows.order_status_id',
'Clients.name',
'ProductTypes.type',
'Suborder.due_date',
'Suborder.created',
],
];
$orders = $this->paginate($collection);
In index.ctp, I have
$this->Paginator->sort('Suborder.created', 'Order Placed'),
$this->Paginator->sort('Suborder.due_date'),
and the error I'm getting is Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Suborder.created' in 'order clause'. How do I get Cake to include the Suborder in the initial query for sorting and pagination?
Edit:
$collection = $this->Orders->find()
->contain([
'Clients',
'CurrentAssignment.Users',
'Workflows.OrderStatuses.Category',
'Workflows.OrderStatuses.Departments' => function ($q) use ($uID) {
return $this->Departments->find()->matching('Users', function ($q) use ($uID) {
return $q->where(['Users.id' => $uID]);
});
},
'ClientProducts.ProductTypes',
'Reviews' => function ($q) {
return $q->where(['review_type_id is not' => 6]);
},
'Reviews.ReviewTypes',
'PublicNotes',
'ActiveReview',
'Suborder',
'Suborder.SuborderTypes',
'Suborders.SuborderTypes',
]);
and $collection is modified with 150 lines of wheres, orWheres, and joins based on a number of conditions.
You have configured the assocaition to use the select strategy, which will use a separate query to retrieve the data (currently wrongly documented), hence you cannot reference it in the main query used for pagination.
So you have to use the default join strategy instead if you want to sort on it.
See also
Cookbook > Database Access & ORM > Associations - Linking Tables Together > HasOne Associations

Cakephp 3, Saving form data on association tables

Trying to set up an example on how to use join table with extra data I have the following set:
table students: id, name, [...]
table courses: id, title, [...]
join table courses_students: id, course_id, student_id, grade, hours_attended
The two base table's :
class StudentsTable extends Table {
public function initialize(array $config) {
$this->belongsToMany('Courses', [
'alias' => 'Courses',
'foreignKey' => 'student_id',
'targetForeignKey' => 'course_id',
'joinTable' => 'courses_students',
'through' => 'CoursesStudents',
]);
}
class CoursesTable extends Table {
public function initialize(array $config) {
$this->belongsToMany('Students', [
'alias' => 'Students',
'foreignKey' => 'course_id',
'targetForeignKey' => 'student_id',
'joinTable' => 'courses_students',
'through' => 'CoursesStudents',
]);
}
And the association table:
class CoursesStudentsTable extends Table {
public function initialize(array $config) {
$this->belongsTo('Courses', [
'alias' => 'Courses',
'foreignKey' => 'course_id'
]);
$this->belongsTo('Students', [
'alias' => 'Students',
'foreignKey' => 'student_id'
]);
}
Having some courses available in the table, I try to add and edit student records. Setting
[courses] => [_ids]
in the student record creates the records in both students table and the association table.
How should the post data array be formed in order to be able to store the grade and hours_attended fields in the association table when saving the student record?
You should configure your form field as the following assuming you are in the Courses form.
echo $this->Form->create($courses);
echo $this->Form->input("Courses.id");
echo $this->Form->input("Courses.title");
echo $this->Form->input("Courses.courses_students.$i.grade");
echo $this->Form->input("Courses.courses_students.$i.hours_attended");
The basic idea is that your forms should exactly follow how the data is formatted when retrieved in your controller.
This will then format your data correctly for you.
Then in your controller, you'll need to pass the associations to patch your entity.
$courses = $this->Courses->patchEntity($this->request->data(), ['associations' => ['CoursesStudents']]);
This will merge your associated request data in your entity, so you can save it.

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.

Resources