I have the table 'role' with fields user_id and role_id.I have get the new value from the another query 154,516 from the for loop.I want to check 154 is in the role table user_id if not exit insert the new field or if exist update the field.In my case update the role_id for the user_id '154' and insert the new row for '516'.
role //table
user_id role_id
210 1
125 2
310 1
154 1
foreach($heads as $head){
$first_count=$first_count+1;
$roleMappingObject = new role_mapping();
$roleMappingObject->user_id = $head->user_id;
$roleMappingObject->role_id = 1;
$roleMappingObject->save (); //this will insert the new row for both 154 and 516 but I want to update '154'
}
In your case it seems like your role_id is not a foreign key, if that's the case you can just use the eloquent functions firstOrCreate/ firstOrNew
The firstOrCreate will search for instance with given data and return that instance or will save that instance.
The firstOrNew will find and return or create instance but doesn't save it in database as you will have to do it by calling save() method.
But if your role_id is foreign key i.e. key id of other table than you should prefer it in way defined in laravel's documentation for many to many relationship changing your role table to role_user and creating relation between users and roles table. In that way you will be able to use the methods attach / detach.
Set a many to many relation between your users and roles
User Model
public function roles()
{
return $this->belongsToMany(Role::class, 'role_user');
}
Role Model
public function users()
{
return $this->belongsToMany(Role::class, 'role_user');
}
And then
$user->roles()->attach($roleId));
Related
So im creating a booking system where you can create maps and assign them to an event. I have 3 tables to handle this, events, maps, and event_maps
I have after reading the Laravel Documentation i decided to set up a belongsToMany relation.
But when i try to retrieve my maps thru my event model i only get one the first row.
in my controller i do
public function displayForm($id)
{
$event = EventModel::find($id);
print_r($event->maps);
}
The result is a Illuminate\Database\Eloquent\Collection Object with the last out of 2 maps, and i can't for my life figger out how to get them all.
My EventsModel
public function maps()
{
return $this->belongsToMany('App\Models\Booky\MapsModel',
// Table name of the relationship's joining table.
'event_maps',
// Foreign key name of the model on which you are defining the relationship
'map_id',
// Foreign key name of the model that you are joining to
'event_id'
);
}
My MapsModel
public function event()
{
return $this->belongsToMany('App\Models\Booky\EventsModel',
// Table name of the relationship's joining table.
'event_maps',
// Foreign key name of the model on which you are defining the relationship
'event_id',
// Foreign key name of the model that you are joining to
'map_id'
);
}
The database looks something like this
events
- id
- lots of irrelevant data
maps
- id
- lots of irrelevant data
event_maps
- id
- event_id
- map_id
I was thinking that perhaps i should use another relation type, but as far as i understand they don't use a relation table like event_maps.
Everything else work as expected.
Anyone who could clear up this mess? :)
The ids are inverted in the relation. Try this:
public function maps()
{
return $this->belongsToMany('App\Models\Booky\MapsModel',
// Table name of the relationship's joining table.
'event_maps',
// Foreign key name of the model that you are joining to
'event_id'
// Foreign key name of the model on which you are defining the relationship
'map_id',
);
}
And:
public function event()
{
return $this->belongsToMany('App\Models\Booky\EventsModel',
// Table name of the relationship's joining table.
'event_maps',
// Foreign key name of the model that you are joining to
'map_id'
// Foreign key name of the model on which you are defining the relationship
'event_id',
);
}
I have to SQL tables: users and roles; The user table consists of an id (PRIMARY), email, password and a role_id (INDEX) column. The role table consists of an id (PRIMARY) and a name column. A user can only have a single role (Admin or User).
This is how my laravel Models look like:
// User Model
public function role()
{
return $this->hasOne(Role::class);
}
// Role model
public function user()
{
return $this->belongsTo(User::class);
}
What i want is, when i get the information of a user, i want to get the corresponding role of that user.
When i place this code in the Artisan Tinker:
// Get user with id=2
App\User::find(2)->role;
This seems logical to me "Find the role belonging to the user with id 2"
But it is throwing this error:
Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'roles.user_id' in 'where clause' (SQL: select * from `roles` where `roles`.`user_id` = 2 and `roles`.`user_id` is not null limit 1)'
How Can i get the role of a User without calling it from the Role model?
Since you have a role_id on users table, you should have belongsTo(Role::class) on User model:
// User Model
public function role()
{
return $this->belongsTo(Role::class);
}
And hasMany(User::class) on role model:
// Role model
public function users()
{
return $this->hasMany(User::class);
}
I believe there should be belongsToMany instead of belongsTo. This should fix the problem. Documentation: https://laravel.com/docs/5.6/eloquent-relationships
Unknown column 'roles.user_id'
This is the error. Your roles table should have user_id column.
Problem
I want to update a row in a pivot table that have 2 primary keys. But updateExistingPivot want only a single primary key.
$user = App\User::find(1);
$user->roles()->updateExistingPivot($roleId, $attributes);
My DB-tables
Campaign
User
Campaign_user (primary keys are user_id and campaign_id)
My Question
Should I change my pivot table so it only have 1 primary key called id. Or can I keep it with 2 primary keys, and still update it, with Eloquent?
I think for best practice you should add a key id in your Campaign_user table, structure should:
Campaign_user
id|user_id|campaign_id
In User Model
public function campaign()
{
return $this->belongsToMany('Campaign', 'Campaign_user','user_id','campaign_id')->withPivot('extra attribute if any');
}
In Campaign Model
public function users()
{
return $this->belongsToMany('User', 'Campaign_user','campaign_id','user_id')->withPivot('extra attribute if any');
}
Now your code is:
$user = App\User::find($userId);
$user->campaign()->updateExistingPivot($campaignId, array('any attribute'=>$value));
I have the following models in my application
User
Group
Task
which have the following relationships
User and Group have a many-to-many relationship
Task and Group have a many-to-many relationship
So basically a user can belong to more than one group and each group can have more than one task.
Following is the table structure.
users
id
name
groups
id
name
tasks
id
name
group_user
id
group_id (foreign key with groups table)
user_id (foreign key with users table)
group_tasks
id
group_id (foreign key with groups table)
task_id (foreign key with tasks table)
Now I want to retrieve all the tasks for the user.
I tried the following approaches and both didn't work.
Approach 1
$user->groups() gives the list of groups for a user
$group->tasks() gives the list of tasks for a group
So I tried
$user->groups()->tasks() but it didn't work.
Approach 2
I tried Has Many Through by adding this to my User model
public function tasks()
{
return $this->hasManyThrough(Task::class, Group::class);
}
but even that didn't work. The following is the error that I am getting
QueryException in Connection.php line 713:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'groups.user_id' in 'field list' (SQL: select `tasks`.*, `groups`.`user_id` from `tasks` inner join `groups` on `groups`.`id` = `tasks`.`group_id` where `groups`.`user_id` = 1)
My guess is that this is happening because it is expecting one-to-many relationship, but I have a many-to-many relationship.
So is there a way to retrieve it without getting all groups and then looping through them?
User Model
public function groups()
{
return $this->belongsToMany('App\Group');
}
Group Model
public function tasks()
{
return $this->belongsToMany('App\Task');
}
Task Model
public function groups()
{
return $this->belongsToMany('App\Group');
}
Retrieving all tasks for a user.
$user = User::find(1);
$user->load('groups.tasks');
$tasks = $user->groups->pluck('tasks')->collapse();
You can also take a look at the extension of the HasManyThrough here: https://github.com/staudenmeir/eloquent-has-many-deep
It helps you to retrieve many sub-levels of your relationships.
In your case, it would be
User -> belongsToMany(Groups) -> blongsToMany (Tasks)
just add your method to the user model like:
public function tasks()
{
return $this->hasManyDeep(
'App\Task',['App\Group']
);
}
I was trying to get the attendance of each user in a course where the users and the courses have many to many relationship and the attendance table is based on the relationship.
But i couldn't call $user->pivot->attendance(); directly i had to call for the pivot object it self so i can call a function to it as you can see in the answer
The Following is a sample of my Database scheme
I need to run
$users=$course->users;
foreach($users as $user)
{
$user->pivot->attendance(); //error in this line
}
this line gives and error
Call to undefined method
Illuminate\Database\Query\Builder::attendance()
users
id
name
etc
courses
id
name
startDate
endDate
course_user
id
course_id
user_id
payment
regDate
status
userattendance
id
course_user_id
time
inOrOut
And here is the CourseUserPivot Class
class CourseUserPivot extends Eloquent {
protected $table ="course_user";
public function course()
{
return $this->belongsTo('Course');
}
public function user()
{
return $this->belongsTo('User');
}
public function attendance()
{
return $this->hasMany('Userattendance','course_user_id');
}
}
P.S: $user->pivot->payment works and displays the attribute but i cant call methods
You can't use $user->pivot->attendance(); as this calls attendance on the user object not on the pivot object
You will have to fetch the pivot object then call the function like so
CourseUserPivot::find($user->pivot->id)->attendance();
make user that where you used withPivot() function you include the id in the array
like in
class Course{
...
...
public function users()
{
return $this->belongsToMany('Candidate')
->withPivot('id',
'summary',
'status',
'payment'
);
}
}
I was trying to accomplish the same thing, and I was having trouble getting it to work like I wanted until I included the 'id' column of my custom pivot model in the withPivot() method.
For some context, my database structure is:
User table
id
Items Table
id
Sets table (defines a set and the items that can be in an instance of it)
id
Set_User table (Custom Pivot Model, instances of a set created by a user)
id, set_id, user_id
Items_SetUser table (items that belong to a set instance that belong to a user)
item_id, setuser_id
I do this in the controller to get all the sets that user has made an instance of, with custom pivot table data:
$user_sets = \Auth::user()->sets()->withPivot('id', 'name')->get();
And then in blade I can access the items associated with each set instance like this:
$set->pivot->set_items()->count()
Without including 'id' in the call to withPivot(), the above is not possible. Note that set_items() is a method on the custom pivot model that defines a relationship with the items table.