Laravel: user id is not added as Foreignkey - php

I want that a user can create e.g. a football club. When the logged in user creates the club (with an Input-field) the foreignkey should automatically appear in the table of the club.
User
User Modell
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
public function wgGroup()
{
return $this->hasOne('WgGroup','user_id');
}
}
WgGroup e.g. for example to create a club
WgGroup Controller
class WGController extends Controller
{
public function dashboard()
{
return view('verified.dashboard');
}
public function createWG(Request $request)
{
$wg = new WgGroup();
$wg->wg_name = $request->wg_name;
$wg->user_id = User::find($request['id']);
$wg->save();
if($wg != null){
return redirect()->back()->with(session()->flash('alert-success', 'Your wg are createt'));
}
return redirect()->back()->with(session()->flash('alert-danger', 'Something went wrong!'));
}
}
WgGrup Model
class WgGroup extends Model
{
use HasFactory;
protected $table = 'wg_groups';
protected $fillable = [
'wg_name', 'user_id'
];
public function user() {
return $this->belongsTo('User');
}
}
WgGroup Database
class CreateWgGroups extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('wg_groups', function (Blueprint $table) {
$table->id();
$table->string('wg_name');
$table->foreignId('user_id')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('wg_groups');
}
}
I don't know exactly why the FK user_id is not added directly to the database.
public function user() {
return $this->belongsTo('User');
}
I thought through this function would happen.

Related

laravel Pivot table for Many to Many relation without laravel convention

I have 2 model user and team, every team can have multiple users and each user can be in any team , so I wanna make a many to many relation.
I'm trying to customize something , I don't wanna use the laravel convention for pivot table.
Here is my User Migration:
class CreateUsersTable extends Migration
{
protected $collection = "table_users";
public function up()
{
Schema::create( $this->collection
, function (Blueprint $table) {
$table->string('_id');
$table->string('username')->unique();
$table->string('password');
}
}
}
And here is my Team Migration :
class CreateTeamTable extends Migration
{
protected $collection = "table_team";
public function up()
{
Schema::create( $this->collection
, function (Blueprint $table) {
$table->string('_id');
$table->string('name')->unique();
}
}
}
So my problem is when I want to create method for the relation in User Model and Team Model.
in Team Model :
public function users()
{
return $this->belongsToMany(User::class, '??', '??' , '??'); // what should I insert in '??'
}
in User Model :
public function teams()
{
return $this->belongsToMany(Team::class, '??', '??' , '??'); // what should I insert in '??'
}
And also how to create Pivot table without using any convention:
pivot table that I created so far:
class CreateUsersTeamTable extends Migration
{
protected $collection = "team_user_pivot";
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create( $this->collection
, function (Blueprint $table) {
$table->id();
$table->string('??'); // please help me to fill this field
$table->string('??'); // please help me to fill this field
$table->timestamps();
});
}
There are '??' in User Model and Team model and Pivot table . help me to fill up each of them
It's not quite as simple as filling in the fields, as you're using a string for the foreign key as well as not follwing the standard namig conventions.
create_team_user_pivot
protected $collection = "team_user_pivot";
public function up()
{
Schema::create($this->collection, function (Blueprint $table) {
$table->id();
$table->string('team__id')->references('_id')->on('teams');
$table->string('user__id')->references('_id')->on('users');
$table->timestamps();
});
}
You also need to edit the models:
User
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
public $table = 'table_users';
public $incrementing = false;
public $keyType = 'string';
protected $primaryKey = '_id';
protected $fillable = [
"_id",
"username",
"password"
];
public function teams()
{
return $this->belongsToMany(Team::class, 'team_user_pivot', 'user__id', 'team__id');
}
}
Team
class Team extends Model
{
use HasFactory;
public $table = 'table_teams';
public $incrementing = false;
public $keyType = 'string';
protected $primaryKey = '_id';
protected $guarded = [];
public function users()
{
return $this->belongsToMany(User::class, 'team_user_pivot', 'team__id', 'user__id');
}
}
you have to create another model with migration
class UserTeam extends Model
{
public $timestamps = false;
protected $table = 'user_has_team';
protected $fillable = ['user_id', 'team_id'];
}
in your team model
public function users()
{
return $this->belongsToMany(User::class, 'user_has_team', 'user_id', 'team_id');
}
in your user model
public function teams()
{
return $this->belongsToMany(Team::class, 'user_has_team', 'team_id', 'user_id');
}

How to delete posts of user at delete account?

I just made a delete function of accounts, but I'm stuck on a problem.I need to also delete posts of user, at delete account.How can I make that? I have table Users, where I have all details from users, and table Posts, where also have user_id and id,caption and image of post.
public function delete($id)
public function delete($id)
{
$profile = User::find($id);
$profile->delete();
Session::flash('remove', "The profile was successfully deleted!");
return redirect('login');
}
Profile.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
protected $guarded = [];
public function profileImage(){
$imagePath = ($this->image) ? $this->image : 'profile/vx2k9TEhkcgaRdOWKvs4lsxqOVmuzwumtwySEnvH.png';
return '' . $imagePath;
}
public function user(){
return $this->belongsTo(User::class);
}
public function followers(){
return $this->belongsToMany(User::class);
}
}
User.php
<?php
namespace App;
use App\Mail\NewUserWelcomeMail;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Mail;
use Actuallymab\LaravelComment\CanComment;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'username', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
protected static function boot()
{
parent::boot();
static::created(function ($user) {
$user->profile()->create([
'title' => $user->username,
]);
});
}
public function posts()
{
return $this->hasMany(Post::class)->orderBy('created_at', 'DESC');
}
public function profile()
{
return $this->hasOne(Profile::class);
}
}
Post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $guarded = [];
public function user(){
return $this->belongsTo(User::class);
}
public function likes()
{
return $this->hasMany('App\Like');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
public function tags()
{
return $this->belongsToMany('App\Tag');
}
}
Migration posts table
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('caption');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
}
I think you could try to delete related model in the controller before the user, i.e.:
public function delete($id)
{
$profile = User::find($id);
$profile->posts()->delete();
$profile->delete();
Session::flash('remove', "The profile was successfully deleted!");
return redirect('login');
}
Or you can go with model event, i.e.:
protected static function boot() {
parent::boot();
static::created(function ($user) {
$user->profile()->create([
'title' => $user->username,
]);
});
static::deleting(function($user) {
$user->posts()->delete();
});
}

Insert into many to many relation table in Laravel

In my laravel project, I have tables that i want to insert a many to many relationship between 2 of them. I want to bind an User(that must be a cleaner kind) to one House of many from current Host user authenticated. To do so, I'm implementing the following function in Controller:
public function hireCleanerToHouse (Request $request)
{
$house_id = $request->houseAssign;
$email = $request->email;
$house = House::find($house_id);
$cleanerUser = User::where('email', $email)->first();
if ($cleanerUser && $house){
$cleanerUser->houses()->attach($house);
}
return response()->json('success', 200);
}
May I am missing a detail of logic that cant let me insert any data. Im pretty new using laravel and the Eloquent ORM.
to help understand better, here are the Models from project. The functions that take care of a separates tables (CRUD) are all working fine.
If there are some other tip to improve legibity or if I'm ignoring some best pratice, I will gladly accept it.
User:
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function host()
{
return $this->hasOne(Host::class);
}
public function cleaner()
{
return $this->hasOne(Cleaner::class);
}
}
House:
class House extends Model
{
protected $fillable = ['name', 'address', 'host_id'];
protected $dates = ['created_at', 'updated_at'];
protected $appends = ['next_cleaning'];
public function host()
{
return $this->belongsTo(Host::class);
}
public function cleaners()
{
return $this->belongsToMany(
Cleaner::class,
'cleaners_houses',
'house_id',
'cleaner_id'
);
}
public function cleanings()
{
return $this->hasMany(CleaningProject::class);
}
public function getNextCleaningAttribute()
{
return $this->cleanings()->orderBy('created_at', 'desc')->first();
}
}
Cleaner:
class Cleaner extends Model
{
protected $dates = ['created_at', 'updated_at'];
public function houses()
{
return $this->belongsToMany(
House::class,
'cleaners_houses',
'cleaner_id',
'house_id'
);
}
public function hosts()
{
return $this->belongsToMany(
Host::class,
'cleaners_hosts',
'cleaner_id',
'host_id'
);
}
public function user()
{
return $this->belongsTo(User::class);
}
public function cleanings()
{
return $this->hasMany(CleaningProject::class);
}
public function getNameAttribute()
{
return $this->user->name;
}
}
Host
class Host extends Model
{
protected $dates = ['created_at', 'updated_at'];
protected $appends = ['name'];
public function houses()
{
return $this->hasMany(House::class);
}
public function cleaners()
{
return $this->belongsToMany(
Cleaner::class,
'cleaners_hosts',
'host_id',
'cleaner_id'
);
}
public function user()
{
return $this->belongsTo(User::class);
}
public function getNameAttribute()
{
return $this->user->name;
}
}
And also the migration that bind many Cleaners to many House is already created:
Migration
class CreateCleanersHousesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('cleaners_houses', function (Blueprint $table) {
$table->increments('id');
$table->integer('cleaner_id')->references('id')->on('cleaners');
$table->integer('house_id')->references('id')->on('houses');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('cleaners_houses');
}
}
here's the solution that I found:
public function hireCleanerToHouse (Request $request)
{
$email = $request->email;
$houseId = $request->idHouse;
$idUserEmail = User::where('email', $email)->first();
$cleaner = Cleaner::where('user_id', $idUserEmail->id)->first();
$house = House::find($houseId);
$cleaner->houses()->attach($house->id);
return response()->json([$cleaner, $house], 200);
}
As you may see the problemn was because the model Cleaner only contains 'id' and 'user_id', so i had to get first the user.id and find the cleaner where user_id = user.id.
Also I don't passed the $house->id in the attach() to match the relationship. Its now working fine. hope it helps someone else.

Laravel - how to change table in orWhere method?

I want to do something like this:
$posts= Status::where('users_id',$user->id)->orWhere(DB::table('user_status_share.user_id', $user->id))->orderBy('created_at', 'DESC')->get();
But I'm getting an error: strtolower() expects parameter 1 to be string, object given - how can I change the table in "orWhere" method? Is this possible? If not - how to use 2 tables in one query?
Schema (Status):
public function up()
{
Schema::create('users_status', function (Blueprint $table) {
$table->increments('id')->unique();
$table->longText('status_text');
$table->integer('users_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users_status');
}
Schema (StatusShare):
public function up()
{
Schema::create('user_status_share', function (Blueprint $table) {
$table->increments('id');
$table->integer('status_id');
$table->integer('user_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('user_status_share');
}
Model Status:
namespace App\Eloquent;
use Illuminate\Database\Eloquent\Model;
class Status extends Model
{
public $timestamps = true;
protected $table = 'users_status';
protected $guarded = ['id'];
public function comments()
{
return $this->hasMany(StatusComments::class);
}
public function likes()
{
return $this->hasMany(StatusLikes::class);
}
public function shares()
{
return $this->hasMany(StatusShare::class);
}
}
Model StatusShare:
<?php
namespace App\Eloquent;
use Illuminate\Database\Eloquent\Model;
class StatusShare extends Model
{
public $timestamps = true;
protected $table = 'user_status_share';
protected $guarded = ['id'];
public function status()
{
return $this->hasOne(Status::class);
}
}
I think you should try something like this
tweak it , i didnt test it
$posts = DB::table('status')->where('users_id',$user->id)->orWhere(function ($query) use ($user) {
$query->table('user_status_share')->where('user_id', $user->id);
})
->get();
can you share more informations because i have a feeling that these can be reached in a simple way using relations (show us database structure and relations in your models)

Eloquent relation setup, two foreign keys to same table laravel 5.2

I have been in big problem, I am maintaining eloquent relationship setup in my project where i am having the following relationship:
User info related to login stored in users table.
User profile related information stored in profiles information.
Users address stored in address table
configurations related information stored in configurations like city, state, country
Efforts
Here is the migration and model and their relationship:
Users migration table:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
}
}
User Model:
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'email', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function profile()
{
return $this->hasOne('App\Profile','user_id');
}
}
Profile migration table:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProfilesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->increments('profile_id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('lastname')->nullable();
$table->string('firstname')->nullable();
$table->string('gender')->nullable();
$table->string('phonenumber', 20)->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('profiles');
}
}
Profile Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
protected $fillable = [
'firstname', 'lastname',
];
public function user(){
return $this->belongsTo('App\User');
}
public function address()
{
return $this->hasOne('App\Address','profile_id');
}
}
Configuration migration table:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateConfigurationsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('configurations', function (Blueprint $table) {
$table->increments('config_id');
$table->string('configuration_name');
$table->string('configuration_type');
$table->string('parent_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('configurations');
}
}
Configuration Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Configuration extends Model
{
public function children() {
return $this->hasMany('App\Configuration','parent_id');
}
public function parent() {
return $this->belongsTo('App\Configuration','parent_id');
}
public function city() {
return $this->hasOne('App\Address', 'city');
}
public function state() {
return $this->hasOne('App\Address', 'state');
}
public function country() {
return $this->hasOne('App\Address', 'country');
}
}
Address Migration Table:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAddressesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('addresses', function (Blueprint $table) {
$table->increments('address_id');
$table->integer('profile_id')->unsigned();
$table->foreign('profile_id')->references('profile_id')->on('profiles')->onDelete('cascade');
$table->string('address')->nullable();
$table->integer('city')->unsigned();
$table->foreign('city')->references('config_id')->on('configurations')->onDelete('cascade');
$table->string('pincode')->nullable();
$table->integer('state')->unsigned();
$table->foreign('state')->references('config_id')->on('configurations')->onDelete('cascade');
$table->integer('country')->unsigned();
$table->foreign('country')->references('config_id')->on('configurations')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('addresses');
}
}
Address Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Address extends Model
{
public function profile(){
return $this->belongsTo('App\Profile');
}
public function city() {
return $this->belongsTo('App\Configuration');
}
public function state() {
return $this->belongsTo('App\Configuration');
}
public function country() {
return $this->belongsTo('App\Configuration');
}
}
I have used Eloquent relation setup, two foreign keys to same table to make my project relationship. But unfortunately above code does not generating desire output. Take a look:
If I use the command Auth::user()->profile->firstname it will print user first name. So if i use Auth::user()->profile->address->city it should print city name stored in configuration table, but instead print name it print the id.
Please suggest me the solution.
Thanks,
Well, I found the solution for my own question. Thanks for everyone who think this question have some worth.
Well, we don't nedd to change user or profile, we just need to make some changes in configuration and address model only.
change
class Address extends Model
{
public function profile(){
return $this->belongsTo('App\Profile');
}
public function city() {
return $this->belongsTo('App\Configuration');
}
public function state() {
return $this->belongsTo('App\Configuration');
}
public function country() {
return $this->belongsTo('App\Configuration');
}
}
to
class Address extends Model
{
public function profile(){
return $this->belongsTo('App\Profile');
}
public function cityConfiguration() {
return $this->belongsTo('App\Configuration', 'city');
}
public function stateConfiguration() {
return $this->belongsTo('App\Configuration', 'state');
}
public function countryConfiguration() {
return $this->belongsTo('App\Configuration', 'country');
}
}
and change
class Configuration extends Model
{
public function children() {
return $this->hasMany('App\Configuration','parent_id');
}
public function parent() {
return $this->belongsTo('App\Configuration','parent_id');
}
public function city() {
return $this->hasOne('App\Address', 'city');
}
public function state() {
return $this->hasOne('App\Address', 'state');
}
public function country() {
return $this->hasOne('App\Address', 'country');
}
}
To
class Configuration extends Model
{
public function children() {
return $this->hasMany('App\Configuration','parent_id');
}
public function parent() {
return $this->belongsTo('App\Configuration','parent_id');
}
public function city() {
return $this->hasOne('App\Address', 'city');
}
public function state() {
return $this->hasOne('App\Address', 'state');
}
public function country() {
return $this->hasOne('App\Address', 'country');
}
}
and that's it. Everything is working fine.

Categories