Laravel 5.7 Relationship One To Many Columns - laravel-5

i have team and match table. All match information save on match table with two team, winner team, match time etc.
on match table i have three field team_1, team_2, winner_team
i want to relation those field with team table
Here is my code
Team Model
class Team extends Model
{
public function league()
{
return $this->belongsTo('App\League');
}
public function matchs()
{
return $this->hasMany('App\Match');
}
}
Match Model
class Match extends Model
{
public function team_1()
{
return $this->belongsTo('App\Team','id');
}
public function team_2()
{
return $this->belongsTo('App\Team','team_2');
}
public function winner()
{
return $this->belongsTo('App\Team','winner');
}
public function league()
{
return $this->belongsTo('App\League');
}
public function teams() {
return $this->team_1()->merge($this->team_2());
}
}
Migration File
Schema::create('matches', function (Blueprint $table) {
$table->increments('id');
$table->integer('team_1')->unsigned()->index();
$table->integer('team_2')->unsigned()->index();
$table->integer('league_id')->unsigned()->index();
$table->integer('winner')->nullable();
$table->dateTime('match_time');
$table->timestamps();
$table->foreign('team_1')->references('id')->on('teams')
->onDelete('restrict')
->onUpdate('cascade');
$table->foreign('team_2')->references('id')->on('teams')
->onDelete('restrict')
->onUpdate('cascade');
$table->foreign('league_id')->references('id')->on('leagues')
->onDelete('restrict')
->onUpdate('cascade');
$table->foreign('winner')->references('id')->on('teams')
->onDelete('restrict')
->onUpdate('cascade');
});

public function team_1()
{
return $this->belongsTo('App\Team', 'team_1');
}
public function team_2()
{
return $this->belongsTo('App\Team', 'team_2');
}

Related

Laravel User Roles recursive

I use Laravel with UserAuth and Roles. All works fine. Now I want to add many Roles.
The Roles Should be Recursive.
Schema::create('role_user', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignedBigInteger('role_id');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
});
Schema::create('role_role', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->unsignedBigInteger('parent_id');
$table->foreign('parent_id')->references('id')->on('roles')->onDelete('cascade');
$table->unsignedBigInteger('child_id');
$table->foreign('child_id')->references('id')->on('roles')->onDelete('cascade');
});
$user->roles(); give me all roles where the user is direct asigned.
Example:
User is in Role1 in role_user table
Role 1 is in Role 2 in role_role table
Role 2 is in Role 3 in role_role table
$user->roles(); Result is Role1.
$user->roles(); Result should contain Role1, Role2, Role3. Not as text. It should be an array
I've to manipulate
public function roles()
{
return $this->belongsToMany(Role::class);
}
But how?
Very Thanks.
You need to do a recursive relationship:
public function childrenRoles()
{
return $this->hasMany(Role::class, 'parent_id', 'id');
}
public function allChildrenRoles()
{
return $this->childrenRoles()->with('allChildrenRoles');
}
You can then access all your roles using
$role = Role::with('allChildrenRoles')->first();
$role->allChildrenRoles->first()->allChildrenRoles; // .. and so on
I've made my own Solutions and it works good.
Role.php:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
public function belongsToUser(User $user,$int)
{
if ($this->hasUser($user)) {
return true;
}
$children = $this->childrenRoles();
if ($int > 10) {
return false;
}
foreach ($children->get() as $child)
{
if ($child->belongsToUser($user,$int+1)) {
return true;
}
}
return false;
}
public function childrenRoles()
{
return $this->belongsToMany(Role::class, 'role_role', 'child_id', 'parent_id');
}
public function hasUser(User $user)
{
return null !== $this->users()->where('user_id', $user->id)->first();
}
}
User.php
public function roles()
{
$r = Role::where('id','<>', 'null');
foreach ($r->get() as $role)
{
if (! $role->belongsToUser($this,0)) {
$r = $r->where('id', '<>', $role->id);
}
}
return $r->get();
}

on cascade delete on many to many relationship in laravel

I had used many to many relationship.i have three table named:product,tag,productstag. in here I want whenever I am going to delete a product it will also delete the relationship it had on productstag table.
public function up()
{
Schema::create('productstags', function (Blueprint $table) {
$table->integer('product_id');
$table->integer('tag_id');
$table->primary(['product_id','tag_id']);
$table->timestamps();
});
}
as you can see I have used product_id and tag_id as the primary key.
so I can't use this
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('products')->onDelete('cascade');
so what's the alternative?
on my product model
public function tags()
{
return $this->belongsToMany('App\Tag','productstags','product_id','tag_id')->withTimestamps();
}
on my tag model:
public function products()
{
return $this->belongsToMany('App\Product','Productstags','tag_id','product_id');
}
on my produduct destroy function:
public function destroy(Request $request,$id)
{
$product=Product::findOrFail($id);
if($request->file('image')==''){
$input=$request->except('photo_id');
}
else{
$input=$request->all();
unlink(public_path()."/images/".$product->image->name);
}
$product->delete($input);
Session::flash('deleted_user','the user has been deleted');
return redirect(route('product.index'));
}
It's not as pretty as cascade but you could override the delete method and do this:
public function delete(){
$this->name_of_the_relationship()->delete();
return parent::delete();
}

How to make a reflexive relationship in Laravel migration and model

I would like to have a table that has a one to many with itself. Eg: I have like a people table that can have many other people.This is how my code looks like:
public function up()
{
Schema::create('people', function (Blueprint $table) {
$table->string('id')->primary();//Here my PK is a string
$table->string('name');
$table->string('title')->nullable();
$table->string('parent_id');//Here is the foreign key of another person
$table->timestamps();
});
}
And in my Person.php model I have this:
public function people()
{
return $this->belongsTo('App\Person')->withDefault();
}
public function person()
{
return $this->hasMany('App\Person');
}
Take a look to this image:
In Person.php model:
public function parent()
{
return $this->belongsTo('App\Person', 'parent_id');
}
public function child()
{
return $this->hasMany('App\Person', 'parent_id');
}
Add parent_id in your migration and define relationship in you model
public function people()
{
return $this->belongsTo('App\Person')->withDefault();
}
public function person()
{
return $this->hasMany(self::class, 'parent_id');
}

One to Many Relationship not working on Laravel

I have three models that are related. First I have User that belongs to a Role. On the other hand, Role has many roles. Role belongs to many permissions and Permissions belongs to many Role. I am using the AuthServiceProvider as suggested by jeffrey way . However, when I'm fetching all the permissions of a User I am having error which is, "Call to a member function getKey() on boolean". Can someone please help me on this. Please refer to the codes below.
User.php
public function role()
{
return $this->belongsTo('App\Role');
}
public function assignRole($role)
{
return $this->roles()->save(
Role::whereName($role)->firstOrFail()
);
}
public function hasRole($role)
{
if(is_string($role)){
return $this->role->contains('name', $role);
}
return !! $role->intersect($this->role)->count();
}
Role.php
class Role extends Model
{
public function users()
{
return $this->hasMany('App\User');
}
public function permissions()
{
return $this->belongsToMany('App\Permission');
}
public function givePermissions(Permission $permission)
{
return $this->permissions()->save($permission);
}
}
Permission.php
class Permission extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
AuthServiceProvider
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
//get all permissions
foreach ($this->getPermissionTo() as $permission ) {
$gate->define($permission->name, function($user) use ($permission){
return $user->hasRole($permission->roles);
});
}
}
public function getPermissionTo()
{
return Permission::with('roles')->get();
}
and lastly, heres the user table that has a foreign key of role_id
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('role_id')->unsigned();
$table->string('id_no')->unique()->index();
$table->string('u_first_name');
$table->string('u_middle_name');
$table->string('u_last_name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});

Laravel BelongsToMany Error - Base table or view not found

I hope this thread find everyone healthy.
What is wrong with the following code? I am getting an error on my many to many relationship. For the past 4 hours i am stuck with this problem. I would be very thankful if you find the bug or source of problem.
Here is my code and tables:
Schema::create('products', function(Blueprint $table)
{
$table->increments('id');
$table->integer('category');
$table->string('thumbnail');
$table->string('images');
$table->string('logo');
$table->string('main_photo');
$table->timestamps();
});
//categories table
Schema::create('product_categories', function(Blueprint $table)
{
$table->increments('id');
$table->string('category');
});
//relationship table
Schema::create('product_productcategory', function(Blueprint $table)
{
$table->increments('id');
$table->integer('product_id'); // the id of the bear
$table->integer('productcategories_id'); // the id of the picnic that this bear is at
});
products model:
class Product extends Model
{
protected $table = 'products';
public function product_category() {
return $this->belongsToMany('App\product_category', 'App\product_productcategory', 'product_id', 'productcategories_id');
}
}
And pivot model
class product_category extends Model
{
protected $table = 'product_categories';
public function product() {
return $this->belongsToMany('App\Product', 'App\product_productcategory', 'productcategories_id', 'product_id');
}
}
Thanks in advance!
Updates: The problem is solved thanks to #mimo.
But now i want to translate the categories in different languages so i created a table like this:
Schema::create('category_translations', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('product_categories')->onDelete('cascade');
$table->integer('locale_id')->unsigned();
$table->foreign('locale_id')->references('id')->on('locales')->onDelete('cascade');
$table->unique(['category_id', 'locale_id']);
});
And my product categories with new relationship to the translations
class product_category extends Model
{
protected $table = 'product_categories';
public function product() {
//return $this->belongsToMany('App\Product', 'App\product_productcategory', 'productcategories_id', 'product_id');
return $this->belongsToMany('App\Product', 'product_productcategory');
}
public function translation($lang) {
return $this->hasMany('App\Category_Translation')->where('locale_id', '=', $lang);
}
}
And in category translation:
class Category_Translation extends Model
{
protected $table = 'category_translations';
public function product_category() {
return $this->belongsTo('App\product_category');
}
}
And finally my Product:
class Product extends Model
{
protected $table = 'products';
public function translation($lang) {
return $this->hasMany('App\Product_Translation')->where('locale_id', '=', $lang);
}
public function product_category() {
//return $this->belongsToMany('App\product_category', 'App\product_productcategory', 'product_id', 'productcategories_id');
//return $this->belongsToMany('App\product_category', 'product_productcategory');
return $this->belongsToMany('App\product_category', 'product_productcategory')->translation(1);
}
}
Now when i run:
$product = App\Product::find(1)->first();
echo $product->product_category;
I get error:
Call to undefined method Illuminate\Database\Query\Builder::translation()
Your migration file is wrong:
//relationship table
Schema::create('product_productcategory', function(Blueprint $table)
{
$table->integer('product_id')->unsigned()->index(); // the id of the bear
$table->foreign('product_id')->references('id')->on('products');
$table->integer('productcategories_id')->unsigned()->index(); // the id of the picnic that this bear is at
$table->foreign('productcategories_id')->references('id')->on('product_categories');
});
This code will made the relationship on the database level.
When you have 12 min free time you can check out this tutorial about many to many relationships in laravel:
https://laracasts.com/series/laravel-5-fundamentals/episodes/21
Update:
you need to update your relationships too:
class Product extends Model
{
protected $table = 'products';
public function product_category() {
return $this->belongsToMany('App\product_category', 'product_productcategory');
}
}
and:
class product_category extends Model
{
protected $table = 'product_categories';
public function product() {
return $this->belongsToMany('App\Product', 'product_productcategory');
}
}

Resources