Trying to define a many-to-many relation with a pivot model in Laravel 8 - laravel

Trying this for hours now and I don't see the error. I have a model 'User' and a model 'Round'. I want to define a n:m-relation with a model 'Flight' as pivot model.
User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\Image\Manipulations;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class User extends Authenticatable implements MustVerifyEmail, HasMedia
{
use Notifiable;
use InteractsWithMedia;
/*
.....
*/
public function rounds() {
return $this->belongsToMany(Round::class)->using(Flight::class);
}
}
Round.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Round extends Model
{
/*
.....
*/
public function users() {
return $this->belongsToMany(User::class)->using(Flight::class);
}
}
Flight.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\Pivot;
class Flight extends Pivot
{
public $incrementing = true;
/*
.....
*/
}
I made several migrations and seeder.
RelationSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Round;
class RelationSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$round = Round::find(1);
$round->users()->sync([1]);
}
}
When running artisan migrate:refresh --seed all tables are created as expected, but the following error occurs on seeding
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'tour.round_user' doesn't exist (SQL: select * from round_user where round_id = 1)
Obviously Laravel is looking for a standard named pivot-table and not for the desired flights-table.
I am using Laravel 8 in a Docker-Container with Sail.
Where is my mistake?

I found my mistake. With using the pivot model, the name conventions for the intermediate table stay valid. It works with
public function rounds() {
return $this->belongsToMany(Round::class, 'flights')->using(Flight::class);
}
and same thing in the inverse definition
public function users() {
return $this->belongsToMany(User::class, 'flights')->using(Flight::class);
}
Thank you everybody who is helping here - I solved 1000s of problems reading your posts!

Related

Class 'App\Scope\__name_Scope' not found in lumen (Laravel micro-framework)

I want to add a global scope to my project. and use it in some models.
so I create this code: (in app/scopes folder)
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class GameStoreScope implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*
* #param Builder $builder
* #param Model $model
* #return void
*/
public function apply(Builder $builder, Model $model)
{
//$storeId = \request()->header('Store');
//dd("asdad");
$builder->where('game_store_id', '=', 1);
}
}
And use it to my model like this:
<?php
namespace App;
use App\Scopes\GameStoreScope;
use Illuminate\Database\Eloquent\Model;
class Player extends Model
{
protected $guarded = [];
protected static function boot()
{
parent::boot();
static::addGlobalScope(new GameStoreScope);
}
but after run my project. always get this FatalError : Class 'App\Scopes\GameStoreScope' not found
Fix namespace ref link https://laravel.com/docs/8.x/eloquent#query-scopes
namespace App\Scopes;
use App\Scopes\GameStoreScope;
use Illuminate\Database\Eloquent\Model;
then run composer dump-autoload

Enforce Global Scope Across all models

we are developing an application based on Laravel Spark. as part of this we want to tie resources to a specfic team.
I know that we can add a global scope such as:
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class TeamScope implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*
* #param \Illuminate\Database\Eloquent\Builder $builder
* #param \Illuminate\Database\Eloquent\Model $model
* #return void
*/
public function apply(Builder $builder, Model $model)
{
$builder->where('team_id', '=',Auth()->user()->currentTeam->id );
}
}
but according to the docs we have to add that to each model that we want to restrict like so:
protected static function boot()
{
parent::boot();
static::addGlobalScope(new TeamScope);
}
my issue with this is that it will be possible to create future models and forget to apply this code. Which could give us a security hole?
is there any way to enforce the scope across the board?
I am not sure if there's a way to globally add the Scope.
In my particular application, we have had to add more responsiblities to our Models. So we created a BaseModel class that extends Laravel's Illuminate\Database\Eloquent\Model.
All new Models then extends the BaseModel instead of Laravel's one.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model
{
protected static function boot()
{
parent::boot();
static::addGlobalScope(new TeamScope);
}
}
For example:
<?php
namespace App;
class Attribute extends BaseModel
{
}
You could also have a trait that you can just use to add this scope to your Model. For example:
trait HasTeamScope
{
protected static function boot()
{
parent::boot();
static::addGlobalScope(new TeamScope);
}
}
}
... and then you can easily re-use that in your Model.
For example:
<?php
namespace App;
class Attribute extends BaseModel
{
use HasTeamScope;
}
Now, based on your question, you might also forget to extend the BaseModel in the first instance or add the Trait in the second one whenever you create a new model.
To solve this, you could easily create a new command to produce models that will use your own stub (which extends the BaseModel or adds the trait whenever you create a new model)
You could create your own base model with the desired global scope that future models would extend.
You should create trait with boot function. Trait named BelongsToTeam.
And in all models add only: use BelongsToTeam;

Laravel 5.6 error in One to Many relationship

My One to Many relationship is like One Sura has many ayah.
Sura Model is like below
Sura.php
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class Sura extends Model
{
public function ayahs()
{
return $this->hasMany('App\Model\Quran', 'surah_id', '_id');
}
}
Quran Model is like below
Quran.php
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class Quran extends Model
{
}
Sura Controller is like below
SuraController.php
<?php
namespace App\Http\Controllers;
use App\Model\Sura;
use Illuminate\Http\Request;
class SuraController extends Controller
{
public function show(Sura $sura)
{
return Sura::find($sura)->ayahs();
}
}
My route is like below
api.php
Route::apiResource('/suras', 'SuraController');
I am getting error like below
I am trying to browse using below URL.
http://127.0.0.1:8000/api/suras/2
SuraController.php
<?php
namespace App\Http\Controllers;
use App\Model\Sura;
use Illuminate\Http\Request;
class SuraController extends Controller
{
public function show($id)
{
return Sura::find($id)->ayahs();
}
}

laravel QueryException table not found

I am not getting it that why i am facing it.
I created a migration name 2018_01_12_035551_create_inquiry_master_table
In my route file assign a route Route::get('lists-inquiry','InquiryController#listinquiry')->name('lists-inquiry');
Created a controller name InquiryController
Controller code:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller as BaseController;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\InquiryMaster;
use Illuminate\Support\Facades\Input;
class InquiryController extends BaseController
{
public function listinquiry() {
$inquiry = InquiryMaster::all();
// dd($inquiry) Here i am getting error
return view('admin.list_inquiry')->with('listinquiry', $inquiry);
}
}
Created a model InquiryMaster
My model look like:
<?php
namespace App;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
class InquiryMaster extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'created_date_time',
'user_id',
'stitch_video_path',
'completion_status'
];
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
}
When i dd($inquiry) in controller it returns error
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'bigball_travel.inquiry_masters' doesn't exist (SQL: select * from inquiry_masters)
It shows table inquiry_masters
and i created inquiry_master
add protected $table = 'inquiry_master'; to InquiryMaster model
so class would look like this.
<?php
namespace App;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
class InquiryMaster extends Model
{
protected $table = 'inquiry_master';
protected $fillable = [
'created_date_time',
'user_id',
'stitch_video_path',
'completion_status'
];
}

"User Model" functions in Laravel 5 don't work

I migrate from laravel 4 to laravel 5. I modified User Model to make it compatible to laravel 5 User Model. The User model in Laravel 4 is like that:
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
// some model relation functions..
...
public function getLocationId()
{
return $this->location_id;
}
}
I modified it and the new User model is like that now:
namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Model as Eloquent;
class User extends Eloquent implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
// some model relation functions (some changes for namespace)
...
public function getLocationId()
{
return $this->location_id;
}
}
However, getLocationId method is now problematic. The following line results in an error.
$auth_location_id = Auth::user()->getLocationId();
This is the error:
BadMethodCallException in Builder.php line 2508:
Call to undefined method Illuminate\Database\Query\Builder::getLocationId()
How can I make the method compatible to laravel 5? Thanks..
Update:
$auth_location_id = Auth::user()->getLocationId; works but returns empty!!
The line below works properly.
$auth_user_id = Auth::user()->getAuthIdentifier();
By my understanding, and short experience with Laravel, all I do is just to use:
use Illuminate\Foundation\Auth\User as Authenticatable;
Then have my Model as:
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
public function getLocationId()
{
return $this->location_id;
}
}
So I may be safe to assume, at least because it works for me that all those contracts has be extended in the facade called when ....\User is used.
PS: this is just an illustration of how I currently use it in Laravel 5.2.*.
Hope this can help or lead you to the solution :)

Resources