Laravel the right way for Many to Many table structure - php

I'm having a many to many relation. Lets say that I have Many users that can be in Many groups and the other way around.
I wan't to make a table that contains the following columns
group_user
id / name / user_id / group_id
Since I have only 3 groups Junior, Middle and Senior I don't want to make another separated table for them. My idea here is to make the following approach:
Creating 3 records in the same table group_user with the following data
id / name / user_id / group_id
1 / Junior / null / null
2 / Middle / null / null
3 / Senior / null / null
So now when I want to insert a group_id I will use this 3 ID's that I just created with NULL user_id and group_id.
My records will look something like this:
id / name / user_id / group_id
4 / NULL / 125 / 1 -> The id of the Junior group that is in the same table.
5 / NULL / 125 / 3 -> The id of the Senior group that is in the same table.
Is this a valid way to do it? How wrong it is?

I would recommend following the correct procedures as follows:
Table 1 users table:
id | name
Table 2 groups table:
id | name
Table 3 group_user pivot table:
id | user_id | group_id
Note: Table 3 should never hold a nullable value
The relation would be as follows, right now we have two models, a User model and a Group model.
both will have a belongsToMany relation towards each other.
Here is the method you will use in the User model:
public function groups()
{
$this->belongsToMany(User::class);
}
And here is the method you will use in the Group model:
public function users()
{
$this->belongsToMany(Group::class);
}
This is the recommended way to continue.

Related

How to sync three laravel models

I have three models: Users, Roles, Organizations.
And a pivot table
organization_role_user
user_id role_id organization_id
1 2 1
I can attach a user to an organization with a role like so:
$u = User::first();
$r= Role::first();
$u->roles()->first()->attach($r, ['organization_id'=> Organization::first()->id]);
and it works fine, the issue now its when I want to update a user: I want to sync pivot table.
I have tried
$u->roles()->sync([1=>['role_id'=>$r->id], 2=>['organization_id'=>$o->id]]);
But it gives me a queryexception saying that organization_id does not have a default value. Any idea how should I sync pivot table while I try to update user details, and note I do not want to keep any existing records on pivot for the user I am trying to update.
Let's assume that your user_id is 1
If you call for example:
$u->roles()->sync([1, 2]);
Laravel will attaching roles_id 1 and 2 to the user_id 1:
user_id role_id
------------------
1 1
1 2
If you want to pass additional intermediate table values you should do it like this
$u->roles()->sync([1 => ['organization_id' => 2], 2 => ['organization_id' => 2]]);
user_id role_id organization_id
-------------------------------------
1 1 2
1 2 2
You have to provide a organization_id in your sync function that's why Laravel return organization_id does not have a default value.

N to N relation in items in same table

I am working with Grocery CRUD (PHP library that creates a full functional CRUD) and I have very basic table of users.
id | first_name | last_name
Some of this users are relatives. So I want to have separate relation table that looks like
id | first_users_id | second_user_id | relation_type
How can I add this relation to Grocery CRUD so while I'll be editing user's profile I would select other users that are relatives providing relation type for each of them?
Without much to go on you should be able to accomplish it like this: https://www.grocerycrud.com/examples/set_a_relation_n_n
You can also reference the docs here for using the function https://www.grocerycrud.com/documentation/options_functions/set_relation_n_n
$crud->set_table('user_table');
$crud->set_relation_n_n('relatives', 'user_user_table', 'user_table', 'id', 'id', 'id');

how to get user name based on id separated by comma in single table

user_id user_name user_friend_list
1 dharmendra 2,3,4,5,6,7
2 jitendra 1,3,4,5,6,7
3 xyz 1,2,6,7
4 pqr 1,3,4
now i want to extract user_id & user name based on user_friend_list id 6 i.e
it will return 1,2,3 user_id & user name dharmendra jitendra and xyz.
i simply use splite function of php but it is so complicated please provide me well shortcut method
thanks & regards
You can use FIND_IN_SET()
select user_id, user_name
from your_table
where find_in_set(6, user_friend_list) > 0
But it would actually be better to change your table design. Never store multiple values in one column!
first thing the table is not normalized that's why the problem exist
you must break this table like this or better :)
table 1
user_id
user_name
table 2
user_id
friend_id
table 2 will have some redundant data though which can be removed by adding a third table as a mapping between table1 and table2
now you can have the following query to get the result
select user_id,user_name from table1 as a join table2 as b on a.user_id=b.user_id where b.friend_id=6;
"SELECT user_id,username from your table WHERE user_id IN (2,3,4,5,6,7)";

Eloquent - Many to many where not found in the pivot table

My DB is set up like...
Accounts --< Accounts_Games >-- Games
Accounts
---------
id INT
Accounts_Games
---------
id INT
account_id INT
game_id INT
Games
---------
id INT
I have managed to get a list of Games by a single Account quite easily using belongsToMany. Now I need to get a list of Games that an Account is NOT joined to.
How can I achieve this in Eloquent?
Thanks
I am didn't know your tables fields in your each tables.
but you can do with this way : add 1 method like this in GamesEloquent file :
public function account_not_join()
{
return $this->belongsToMany('Account', 'accounts_games', 'game_id', 'account_id')->where('is_join', 0);
}

codeigniter db->select handle mysql joins automaticly

table
ID|owner_id|work_id|lorem|etc|
1 |00123 | 00213 |XXXXX|XXX|
2 |00124 | 00213 |XXXXX|XXX|
owner_id (fk) owners.id (owners[id,name,etc])
work_id (fk) work.id (work[id,name,etc])
question is can I set codeigniter that when I
select(table.*,work.name as work,owners.name as owner) from table
it automatically handle joins since that table already contain the fk-ref ? or I must include join('owner','owner.id=table.owner_id) ?
actually all what I want is that when I select a table that contains a fk this fk column is replaced with one column from ref row by just passing the column name on ref table without having to worry about creating a specific function in my module for that each query.
My current solution:
was to create a view for each table that contain a relation and replace all fk columns with desired ref value, but since i have 6 tables 5 of them with fk,i now have 6 tables and 5 view (11 tables)in db which is really kind confusing for me, so any smarter way to do this ?
I think you are making some confusion on what FK is and what it does within a table.
FK constraint grants data integrity when it's present and relates data within tables. It doesn't join anything.
If you want to select records across related tables, you either use a
SELECT * FROM table1,table2 WHERE table1.K1 = table2.FK1
or
SELECT * FROM table1 JOIN table2 ON table1.K1 = table2.FK1
AND YES, you need to tell CodeIgniter to do those queries

Categories