CakePHP 2.X - Couple of questions on HasMany Relation - php

I'm having some problems using this old framework I had to manage.
I have these tables:
GROUP -> HAS MANY -> MONITOR
MONITOR -> HAS MANY -> [ EVENTS , ZONE ]
MONITOR -> HAS_AND_BELONGS_TO_MANY -> GROUP
For GROUP -> MONITOR Relationship, a join tables has been created by Cake called GROUP_MONITOR.
This is the HasMany Configuration on Group Model:
'Monitor' => array(
'className' => 'Monitor',
'joinTable' => 'Groups_Monitors',
'foreignKey' => 'GroupId',
'associationForeignKey' => 'MonitorId',
QUESTION 1:
I'm trying to retrieve all groups with all the related monitors. I found the recursive key that allow to go deeply in relations:
$all_groups = $this->Group->find('all', array('recursive' => 1));
I got this error:
Column not found: 1054 Unknown column 'Monitor.GroupId' in 'field list'"
It seems like Cake is not using the "Groups_Monitors" table but is searching groupId in the Monitor Table;
QUESTION 2:
Trying to get Groups querying Monitors, with recursive to 1 I got all groups correctly but also all other Monitor's HasMany relations.
$all_monitors = $this->Monitor->find('all',array("recursive" => 1));
Is it possible to exclude some HasMany relations in find to have a reduced amount of data?

You say you have
GROUP -> HAS MANY -> MONITOR
"Has many" doesn't use a join table. The way this relation works is "monitor" has to have a foreign key that references a group. If you want to use the join table you should use "has and belongs to many".
For Q2, use the containable behavior. You'll be able to specify in detail what data and which models you want fetched from the DB. https://book.cakephp.org/2/en/core-libraries/behaviors/containable.html

Related

Laravel-Backpack Getting data of 2 tables by join

I'm new using backpack for laravel and I'm trying to understand how could show data from DB in the default view that backpack use to display rows. I already read the documentation from the site but it's really poor, and have a lot of questions.
I have 2 models linked by join, for example:
Table 1 Table 2
-id -id
-name -phone
-age -description
-table2_id
How can I display the attributes from table 2 in table 1 list view?. Backpack haves this view to list elements of modules
I want to see on that table the combination of the 2 tables...Any code that could help me ?. Thank you for your help.
Backpack creates CRUD Panels for you Eloquent Models. Not your database tables. So in order to have columns showing up that show elements from another table, you need to properly define the relationships between those Models. Then you can use the select column to show that connected entry.
[
'name' => 'rm_id',
'label' => 'Relationship Manager',
'type' => 'select2',
'model'=>config('permission.models.role'),
'options' => (function ($query) {
return $query->where('roles.name', 'Relationship Manager')
->join('model_has_roles', 'model_has_roles.role_id','=','roles.id')
->join('users', 'model_has_roles.model_id','=','users.id')
->select('users.id','users.name')->get();
}),
'attribute'=>'name',
],

How to store multiple value in a field which has relationship with other table

I am working on a 'contact databse' using mysql database and codeigniter. Some of my table structure is as below
Organization -> fld_id
fld_orgname
fld_orgaddress
Department -> fld_id
fld_org_id (has relationship with organization)
fld_deptname
fld_details
Designation -> fld_id
fld_dept_id (has relationship with organization)
fld_desgname
usertable -> fld_id
fld_desg (has relationship with Designation)
fld_dept (has relationship with Department)
fld_org (has relationship with organization)
Now the problem is, sometime a person may work in multiple organization. Then how could i insert this multiple value sequentially to usertable?
One answer is to create another cross reference table for storing the connection between a user and an organization. That way there can easily be a one to many relationship between a person and organizations
user_org => fld_id
user (usertable.fldid)
org (Organization.fld_id)
You should then remove fld_org (has relationship with organization) from usertable
(Sorry about my english if im not clear)
If i'm understanding this correctly a user can work in more than one organization and an organization can have multiple users, uno solution may be to create a junction table
JUNCTION_ORG_USER -> fld_id_user (usertable) REFERENCES usertable(fld_id)
-> fld_id_org (organization) REFERENCES organization(fld_id)
Or if u dont want (or can't) to normalize, u can repeat the row changing the organization id
Also as u are using codeigniter, and this applies if u create a junction table,
u can use
$this->db->insert_batch('table_name', $array);
Just build the array like the documentation indicated
$data = array(
array(
'fld_id' => 'TheUserId',
'fld_org' => 'OrganizationId_1'
),
array(
'fld_id' => 'TheUserId',
'fld_org' => 'OrganizationId_2'
)
);
$this->db->insert_batch('mytable', $data);
Hope my answer helps u.

Laravel - pivot relationship & naming the relationships

I have a table 'shop_visit_count' with columns ( 'user_id', 'shop_id', 'visit_count', 'created_at', 'updated_at' ),
A user can have many restaurant visit_counts, A restaurant can have many different user visit_counts of the same restaurant
the visit_count will be updated everytime the user visits a restaurant
Should I convert this to a pivot table?, or Should I add/keep the incremental Id primary key field?
If I need to convert to a pivot table, what should I name this many-to-many relationship? since this is not like the usual 'user', 'shop', 'shop_user' type relationship, but about the visit_count?
You can keep the table "shop_visit_count", it is ok. Pivot Tables don't bring much more.
Have you troubles with that actual table ?

Reflexive many-to-many relationship in CakePHP

I've been searching around for a definitive answer to this issue but have been unable to resolve it. I've recently been working with (and learning) CakePHP and have run across an obstacle. To simplify my database, let's say we simply have two tables:
persons
relationships (or persons_persons)
Persons has a many-to-many relationship with itself - and indeed, two people can have more than one relationship with each other:
persons
-------
*person_id*
name
relationships
-------------
*relationship_id*
person_1_id
person_2_id
start_date
end_date
Now, if I want to say Person1 (id=1) is married to Person2, I would have one entry in the relationships table. person_1_id would be 1, and person_2_id would be two.
I can create this relationship in CakePHP, and show the lists of relationships (and persons) per Person record. However, it's a unidirectional relationship: for Person 1, the query will only pull Relationship objects where person_1_id matches. If I want to query the relationships for Person 2, I'd have to have a second identical row, with the person_1_id and person_2_id swapped.
Here's the models:
class Member extends AppModel {
public $hasMany = array(
'Relationships' => array(
'className' => 'Relationship',
'foreignKey' => 'person_1_id'
)
);
}
class Relationship extends AppModel {
public $belongsTo = array(
'Person1' => array(
'className' => 'Person',
'foreignKey' => 'person_1_id'
),
'Person2' => array(
'className' => 'Person',
'foreignKey' => 'person_2_id'
)
);
}
Any suggestions? It doesn't make logical sense to duplicate Relationship entities when person_1_id is actually no separate than person_2_id.
I think you've got two options:
1. Duplicate the Relationship Record
Look at it from a different perspective; Consider the concept of directed vs. an un-directed graph. Your current schema supports a directed edge leaving one object (Person) and arriving at another. Agreed from your application's perspective, a person can't have a relationship with another, without them knowing.
The amount of space within the database would be negligible if you did choose to go down this route and would be less complex to implement than option 2. Bare in mind that you should put in place measures to ensure the relationship remains symmetrical at all times.
2. Handle the Relationship Asymmetry in Your Application
Create another relationship so your model looks like the following:
class Member extends AppModel {
public $hasMany = array(
'RelationshipsA' => array(
'className' => 'Relationship',
'foreignKey' => 'person_1_id'
),
'RelationshipsB' => array(
'className' => 'Relationship',
'foreignKey' => 'person_2_id'
)
);
}
You then have separate bins for your relationships depending on which side of the relationship your person exists. You then have to put extra logic everywhere so that you can handle the relationship bins as one homogeneous collection.
I'm sorry I couldn't be any more helpful but I can't think off the top my head, how to implement an un-directed graph without building it on top of a directed one.
Update 05/05/13
To summarize the comment thread, setting the finderQuery on the hasMany association can mask the need to duplicate the lookup for the association with person_2_id (Documentation):
'Relationship' => array(
'finderQuery' => 'SELECT Relationship.* FROM relationships AS Relationship WHERE Relationship.person_2_id = {$__cakeID__$} OR Relationship.person_1_id = {$__cakeID__$};'
)
This hides the complex retrieval mechanism but storing relationships may require further thought.

cakephp friendship between users Linking models together

What I need:
A facebook-like friendship system.
User (A) sends a requests for a friendship with User (B)
User (B) confirmes the request
User (A) and User (B) are friends now
My problem:
I'm confused how to work this out. I read a lot on the internet but it did not really helped me...
My Questions:
What kind of link is it in CakePHP? Is it hasAndBelongsToMany? Or hasMany? Or ...?
How do I realise it in the datebase correctly?
How do I link it in the model?
What I already did:
Table: users
Name: id, username, password, ...
users_users table: id, user_id, friend_id, approved
Model:
'User' => array(
'className' => 'User',
'joinTable' => 'users_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
);
"#tereško Thank you! But I get an error: Error: An Internal Error Has Occurred"
First to answer your comment about the "internal error" you getting:
Try setting debug to 2 in config.php you will realize that you will start getting much more understandable errors.
Regarding your first question:
1. Your relation basically looks to like hasMAny since every user has friends.
HABTM will also work here, but it is much more complicated. This decision (what relations to use) also depends on other parts of your system - i.e. for what and how you'd like to use this data in other parts of it.
2. Read here
3. Read there again
A bit more on HABTM and hasMany through the jon model (if you need to store any additional data in the join table while using the same idea as HABTM).
What to do when HABTM becomes complicated?
By default when saving a HasAndBelongsToMany relationship, Cake will delete all rows
on the join table before saving new ones. For example if you have a Club that has 10 Children associated. You then update the Club with 2 children. The Club will only have 2 Children, not 12.
Also note that if you want to add more fields to the join (when it was created or meta information) this is possible with HABTM join tables, but it is important to understand that you have an easy option.
HasAndBelongsToMany between two models is in reality shorthand for three models associated through both a hasMany and a belongsTo
association.
Your current DB structure is awful. I didn't get why you need a table called table - or maybe I got this wrong.If you intend to use HABTM you do not need to create the join model at all - cake will automatically create and populate it for you.
Some more info for HATBM:
Here
There
Here
There

Categories