I'm trying to understand how I can join the tables users and teams to members in fact ?
Users Table:
id | name | email | password
1 alain alain#gmail.com *****
2 eric eric1#gmail.com *****
Teams Table:
id | name
1 R.O.S
2 Stephanois
Members Table:
id | user_id (email) | team_id (name)
1 1 1
2 2 1
DataBase:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function up()
{
Schema::create('members', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->integer('team_id')->unsigned()->nullable();
$table->foreign('team_id')->references('id')->on('teams');
$table->timestamps();
});
}
public function up()
{
Schema::create('teams', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
}
User Model:
protected $fillable = [
'name', 'email', 'password',
];
public function team(){
return $this->hasOne('App\Team', 'user_id', 'id'); ?
}
public function member(){
return $this->hasOne('App\Member', 'user_id', 'id'); ?
}
Team Model:
protected $fillable = [
'user_id', 'name'
];
public function member(){
return $this->hasMany('App\Member', 'team_id'); ?
}
public function user(){
return $this->belongsTo('App\User', 'id', 'user_id'); ?
}
Member Model:
protected $fillable = [
'id', 'user_id', 'team_id'
];
public function team(){
return $this->belongsTo('App\Team', 'team_id');
}
public function user(){
return $this->belongsTo('App\User', 'id', 'user_id'); ?
}
I thank you in advance for your help
Edit: when I log in with the user 'alain#gmail.com' I don't retrieve the information for the user 'alain#gmail.com' ? ie user_id and team_id.
public function index(Request $request)
{
$user = $request->user();
$members = Member::query()
->when($user->hasRole('admin') !== true, function (Builder $query) use ($user) {
$query->where('id???', $user->email); ????
})
->when($request->has('search'), function (Builder $query) use ($request) {
$query->where('name??', 'like', '%' . $request->input('search') . '%');
})->with('team:id,name')
->paginate(5);
return view('admin.members.index', compact('members'))
->with('display_search', $user->hasRole('admin'));
}
Which one is you're trying to achieve is not enough clear. If I guess, you want to find out which user is in which team then, in this situation you can go through -
User.php model -
protected $fillable = [
'name', 'email', 'password',
];
public function member(){
return $this->belongsTo('App\Member', 'user_id', 'id');
}
Member.php model -
protected $fillable = [
'id', 'user_id', 'team_id'
];
public function team(){
return $this->belongsTo('App\Team', 'team_id');
}
public function user(){
return $this->belongsTo('App\User', 'user_id', 'id');
}
Team.php model (keep as it is for now)-
class Team extends Model
{
protected $fillable = [
'name'
];
}
And finally call your members those are already in a team in your controller method-
$members = Member::with('team', 'user')->get();
return view('your-blade-file-name', compact('members'));
And, in your blade file -
#foreach($members as $member)
<p>Name: {{ $member->user->name }} , Email: {{ $member->user->email }} , Team - {{ $member->team->name }}</p>
#endforeach
Output:
Name: alain, Email: alain#gmail.com , Team - R.O.S
Name: eric, Email: eric1#gmail.com , Team - R.O.S
If you want a user can belong to a single team, then you don't need an intermediate table. Just add a column in the user table like team_id that will hold the value of which team the user belong.
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->unsignedInteger('team_id'); //make it nullable or anything based on your need
$table->rememberToken();
$table->timestamps();
});
Schema::create('teams', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
And now make the relationships in the models:
User Model
protected $fillable = [
'name', 'email', 'password','team_id'
];
public function team()
{
return $this->belongsTo('App\Team', 'team_id');
}
Team Model
protected $fillable = [
'name'
];
public function users()
{
return $this->hasMany('App\User', 'team_id');
}
In the above relationships a user belongs to a single team and a team has many users. I am pretty sure you are trying to achieve this. Feel free to ask if you find anything hard to understand.
Look you don't need the intermediate model Member. If you want a many to many relationship then you need to use an intermediate table.
Related
Hello I need a help with laravel 8 many to many relationship pivot table, when I updating or deleting data in API.
These are my files info.
Firstly I created two tables:
Companies (migration file)
public function up()
{
Schema::create('companies', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamps();
});
}
Contacts (migration file)
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamps();
});
}
After this created pivot table company_contact (migration file)
public function up()
{
Schema::create('company_contact', function (Blueprint $table) {
$table->foreignId('company_id')->constrained();
$table->foreignId('contact_id')->constrained();
});
}
Models looks like this:
Company model
class Company extends Model{
use HasFactory;
protected $fillable = [
'name',
'email'
];
public function contacts()
{
return $this->belongsToMany(Contact::class);
}
}
Contact model
class Company extends Model{
use HasFactory;
protected $fillable = [
'name',
'email'
];
public function contacts()
{
return $this->belongsToMany(Contact::class);
}
}
My routes file
Route::apiResource('companies', CompanyController::class);
My company controller
class CompanyController extends Controller{
public function index()
{
return CompanyResource::collection(Company::all());
}
public function store(CompanyStoreRequest $request)
{
$company = Company::create($request->validated());
$company->contacts()->attach($request->input('contact_id'));
return new CompanyResource($company);
}
public function show(Company $company)
{
//
}
public function update(CompanyStoreRequest $request,Company $company)
{
$contacts = Company::where('id', $company->id)->contacts()->get();
$company->contacts()->sync($request->input(['contact_id']));
$company->update($request->validated());
return new CompanyResource($company);
}
public function destroy(Company $company)
{
}
}
Company store request
public function rules()
{
return [
'name' => ['required'],
'email' => ['required', 'email'],
'contact_id' =>['required']
];
}
company resource
public function toArray($request)
{
//return parent::toArray($request);
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'contact_count' => $this->contacts()->count()
];
}
Maybe somebody can help my to write correct store() and destroy() methods in to company controller. For example when I updating company data also I want to add more contacts and to save these contacts id's in the pivot table.
With destroy method, when I delete certain company, also I want automatically delete these id’s in pivot table (relation company with contacts).
Thanks for any help.
First, you can pass the data of the contacts in an array together with the company's, using an array for several contacts and to record with the relationship use a foreach with the attach method, search on it. About the deletion you can use the softDelete, search on it too, it makes the cascade deletion of the items.
I have this model :
class User extends Authenticatable
{
protected $fillable = [
'email',
'password',
'role_id',
];
.........
public function language() {
return $this->hasOne(Language::class, 'language_id');
}
}
And Language model :
class Language extends Model
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'iso'
];
/**
* #return BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class);
}
Now When I try to save user :
$newUser->language()->save(Language::find($input['language']));
I get the error:
Column not found: 1054 Unknown column 'language_id' in 'field list' (SQL: update `languages` set `language_id` = 4, `languages`.`updated_at` = 2021-08-02 13:51:32 where `id` = 1)"
User migration :
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->integer('role_id')->default(UserRoles::TRANSLATOR);
$table->integer('language_id')->references('id')->on('languages')->nullable();
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
}
Language migration :
public function up()
{
Schema::create('languages', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('name');
$table->string('iso')->unique();
});
}
I confirm that I have language id inside users table and I don't have user_id inside language table, because I want to keep just language_id inside table. What can I try next?
When you have hasOne in User model:
public function language() {
return $this->hasOne(Language::class, 'language_id');
}
eloquent assumes that languages table would have language_id. Hence the error 'no language_id in languages table'
So, hasOne should be defined in the the Language model.
//Language model
public function user() {
return $this->hasOne(User::class); //this assumes users table would have language_id
}
And, the belongsTo should be defined in User model.
//User model
public function language() {
return $this->belongsTo(Language::class);
}
as the first answer, change the sintax of your relationship and add the language_id to the fillable array
user model
protected $fillable = [
'email',
'password',
'role_id',
'language_id'
];
public function language() {
return $this->belongsTo(Language::class);
}
and on user creation
$user = User::create(
'email' => ...
'password' => ...
'role_id' => ...
'language_id' => $input['language']
);
you can see more here https://laravel.com/docs/8.x/eloquent-relationships#the-save-method, so in this case if you want to use the save method on this relation you must do it like
$language = Language::find($input['language']);
$language->user()->save($newuser);
I suggest use the Laravel documentation sintax for the relationship in migration
$table->foreignId('language_id')->constrained()->nullable();
I built two models User and Institution.
How do I update the pivot data between them, after adding additional Pivot columns?
<?php
class User extends Authenticatable
{
public function institutions()
{
$pivots = ['id', 'program_choice', 'session'];
return $this->belongsToMany('App\Institution')
->withPivot($pivots);
}
}
class Institution extends Authenticatable
{
public function users()
{
$pivots = ['id', 'program_choice', 'session'];
return $this->belongsToMany('App\User', 'institution_user')
->withPivot($pivots);;
}
}
Here are the migrations
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->integer('user_id')->unsigned();
$table->rememberToken();
$table->timestamps();
});
}
class CreateInstitutionsTable extends Migration
{
public function up()
{
Schema::create('institutions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->unique();
$table->string('city')->nullable();
$table->string('state')->nullable();
$table->string('country')->nullable();
$table->string('address')->nullable();
$table->string('user_id')->nullable();
$table->string('postal_code')->nullable();
$table->timestamps();
});
}
}
This is the what the pivot table looks like
I am able to attach the information to the pivot table
public function storeInstitution(Request $request)
{
$user_id = auth()->user()->id;
$user = User::find($user_id);
$institution_id = $request->input('institution_id');
$user_program_choice = $request->input('program_choice');
$user_session = $request->input('session');
$user_inst = array(
'program_choice' => $user_program_choice,
'session' => $user_session,
'user_id' => $user_id,
'institution_id' => $institution_id
);
$user->institutions()->attach($institution_id, $user_inst);
return 'success';
}
But unable to update the attached pivot E.g I can't change the program_choice, particle physics to something like digital art
Here's my current code
public function updateInstitutions(Request $request, $pivot_id)#TODO id is pivot_id
{
$user_id = auth()->user()->id;
$user = User::find($user_id);
$institution_id = $request->input('institution_id');
$pivot_attributes = array(
'user_id' => $user_id,
'institution_id' => $institution_id,
'session' => $request->input('session'),
'program_choice' => $request->input('program_choice'),
);
$user->institutions()->updateExistingPivots($institution_id, $pivot_attributes, false);
return 'success';
}
How do I update my pivot data, using the pivot id?
Check the documentation regarding this aspect.
Updating A Record On A Pivot Table
If you need to update an existing row in your pivot table, you may use
updateExistingPivot method. This method accepts the pivot record
foreign key and an array of attributes to update:
$user = App\Models\User::find(1);
$user->roles()->updateExistingPivot($roleId, $attributes);
I have the following schema
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('userName')->default('');
$table->string('userEmail')->default('');
$table->tinyInteger('active')->default(1);
$table->timestamps();
});
Schema::create('user_groups', function(Blueprint $table)
{
$table->increments('id');
$table->string('groupName')->default('');
$table->timestamps();
});
Schema::create('users_user_groups', function(Blueprint $table)
{
$table->integer('userId')->unsigned()->index();
$table->foreign('userId')->references('id')->on('users')->onDelete('cascade');
$table->integer('groupId')->unsigned()->index();
$table->foreign('groupId')->references('id')->on('user_groups')->onDelete('cascade');
$table->timestamps();
});
Essentially, a User can be apart of many Groups, and a Group can have many Users.
class User extends Model
{
protected $table = 'users';
protected $guarded = [];
public function groups()
{
return $this->belongsToMany('App\Group', 'users_user_groups')->withPivot('userId', 'groupId');
}
}
class Group extends Model
{
protected $table = 'user_groups';
protected $guarded = [];
public function user()
{
return $this->belongsToMany('App\User', 'users_user_groups')->withPivot('userId', 'groupId');
}
}
I think the Models are ok. I then have an updateUsers function in my controller
public function updateUsers()
{
$users = Helper::returnUsersFromLdap();
DB::table('users')->update(array('active' => false));
foreach($users as $userName => $userData) {
$user = User::firstOrNew(['userName' => $userName]);
foreach ($userData as $userEmail => $userDepartment) {
$user->userEmail = $userEmail;
$user->active = true;
$userGroups = Helper::returnGroupsFromLdap($userEmail);
foreach($userGroups as $group) {
$user->groups()->sync($group);
}
}
$user->save();
}
Session::flash('flash_message', 'Users updated');
Session::flash('flash_type', 'alert-success');
return Redirect::route('users.index');
}
I essentially get a user list from Active directory, loop this, and add the my users table. For each user, I call returnGroupsFromLdap passing the users email as a parameter. For each user, this will return the groups that user is in like so
array:3 [▼
0 => "Group1"
1 => "Group2"
2 => "Group3"
]
My question is how can I link the user groups to a user? So I loop each group and then add it to my user_groups table? But then where do I populate the pivot table I created?
Any advice on this matter appreciated.
Thanks
You can use the sync method to update the user groups from the user model:
$user->groups()->sync([1, 2, 3]);
Where [1, 2, 3] is an array with group ids. Laravel will know to save this relation in the table that you specified in the belongsToMany() relatiotnship in the model.
But you might have to specify the column names because by default Laravel uses another naming convention:
return $this->belongsToMany('App\Group', 'users_user_groups')->withPivot('userId', 'userGroupsId');
Check the documentation for more details: https://laravel.com/docs/5.2/eloquent-relationships#many-to-many
Try:
public function up()
{
Schema::create('users_user_groups', function(Blueprint $table)
{
$table->increments('id');
$table->integer('userId')->unsigned();
$table->integer('userGroupsId')->unsigned();
});
Schema::table('users_user_groups', function(Blueprint $table) {
$table->foreign('userId')->references('id')->on('users');
$table->foreign('userGroupsId')->references('id')->on('user_groups');
});
}
I am new to laravel. i am having difficulties to store foreign key value in database. I have read the documentation, searched on stackoverflow. But its confusing me more.
I have a User table and an idea table. User can create many idea. Let me show the code:
Controller function:
public function storePost(IdeaRequest $request) {
Idea::create([
'title' => $request->input('idea_title'),
'user_id' => $request->hasMany('user_id'),
'image' => $request->file('idea_image')->move('images'),
'info' => $request->input('idea_info'),
'communitySelection' => $request->input('selection'),
'location' => $request->input('idea_location'),
'goal' => $request->input('idea_goal'),
'description' => $request->input('idea_description')
]);
}
Idea Model:
class Idea extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'idea_title', 'idea_info','user_id', 'idea_image', 'idea_description', 'duration', 'idea_goal', 'pledge_amount', 'set_equity',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'remember_token',
];
public function Post() {
return $this->hasMany('User');
}
}
Idea Migration:
public function up()
{
//
Schema::create('ideas', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('idea_title');
$table->string('idea_info', 150);
$table->string('idea_image');
$table->string('selection');
$table->longText('idea_description');
$table->string('idea_location');
$table->integer('idea_goal')->unsigned();
$table->integer('pledge_amount')->unsigned();
$table->string('set_equity')->nullable();
$table->rememberToken();
$table->timestamps();
});
}
User Migration:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name',50);
$table->string('email')->unique();
$table->string('password',32);
$table->string('profile_picture')->nullable();
$table->string('address');
$table->string('phone_number',15);
$table->boolean('status')->nullable();
$table->string('user_type',15);
$table->string('credit_card',16)->unique();
$table->rememberToken();
$table->timestamps();
});
}
It can be seen that foreign key is being set. I am unable to store the value of foreign key on a user table. Any help would be appreciated.
In the Idea Migration, you can declare the foreign key like this
public function up()
{
//
Schema::create('ideas', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('idea_title');
$table->string('idea_info', 150);
$table->string('idea_image');
$table->string('selection');
$table->longText('idea_description');
$table->string('idea_location');
$table->integer('idea_goal')->unsigned();
$table->integer('pledge_amount')->unsigned();
$table->string('set_equity')->nullable();
$table->rememberToken();
$table->timestamps();
});
//Declare foreign key
Schema::table('ideas', function(Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')
->onDelete('restrict')
->onUpdate('restrict');
});
}
I do not agree with the relation you added in the Idea Model. You should use belongsTo instead of hasMany. And according to the comments, change Post() to User() .
public function User() {
return $this->belongsTo('User');
}
If so, you need also change 'user_id' => $request->hasMany('user_id') in the Controller function.