RelationShip Eloquent hasOne - laravel

I do not understand how the relationShips are working with Eloquent. Imagine an user with one role. I wrote this in my model User :
public function role()
{
return $this->hasOne('App\Models\Role');
}
And this in my model Role :
public function user()
{
return $this->belongsTo('App\User');
}
After that i would like to retrieve the role of the user connected , like that :
Auth::user()->role->role_name
But it throw an exception :
Undefined column: 7 ERROR: column roles.user_id does not exist
Does it not work like that?

You're missing the user_id foreign column in the roles table, Eloquent assumes that column to exist in order to link a User with a Role
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('role_name');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
Update: given a hasOne relationship
App\User model
public function role()
{
return $this->hasOne('App\Models\Role');
}
App\Model\Role model
public function user()
{
return $this->belongsTo('App\User');
}
DatabaseSeeder
$user = factory('App\User')->create();
$user->role()->create([
'role_name' => 'Admin'
]);
routes/web
use Illuminate\Support\Facades\Auth;
Route::get('/', function () {
return Auth::user()->role->role_name;
});
Results => Admin

You should use the belongsTo() relationship in your User model for the role relationship :
public function role()
{
return $this->belongsTo('App\Models\Role');
}

Related

Can't create one to many relationship on same model

I want to create sponsors users on my website. I use the same model as relationship.
User.php (model):
public function sponsor(): HasMany
{
return $this->hasMany(self::class, 'sponsored_id', 'sponsor_id');
}
public function sponsored(): BelongsTo
{
return $this->BelongsTo(self::class, 'sponsor_id', 'sponsored_id');
}
Sponsor rows :
Schema::table('users', function (Blueprint $table) {
$table->foreignId('sponsor_id')->nullable();
$table->foreignId('sponsored_id')->nullable();
});
My UserSeeder:
$sponsor = User::factory()->create(['name' => 'sponsor']);
$sponsor->sponsor()->save(
User::factory()->make()
);
As per your comment you are trying to retrieve one record from sponser so it should be
$sponsor->sponsor()->first()

Laravel define belongsToMany relation ships without providing second parameter

In laravel i try to make a simple relation-ship between two table as users and wallets without providing second parameter, but when i try to access between them i get error:
Base table or view not found: 1146 Table 'sample.user_wallets' doesn't exist
//user
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('parent_id')->nullable();
//...
$table->softDeletes();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
//wallets
Schema::create('wallets', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('wallet_name');
$table->string('wallet_number');
$table->timestamps();
});
//user_wallet
Schema::create('user_wallet', function (Blueprint $table) {
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->foreignId('wallet_id')->constrained()->cascadeOnDelete();
$table->primary(['user_id','wallet_id']);
});
User model:
public function wallet(): BelongsToMany
{
return $this->belongsToMany(UserWallet::class);
}
Wallet model:
public function user(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
and by this below code i try to access user's wallets:
$this->user_wallets = auth()->user()->with('wallet')->get();
IN Your User Model:
change
public function wallet(): BelongsToMany
{
return $this->belongsToMany(UserWallet::class);
}
To : THis
public function wallets(): BelongsToMany
{
return $this->belongsToMany(Wallet::class,'user_wallet');
}
In Your Wallet Model:
public function users(): BelongsToMany ///not user
{
return $this->belongsToMany(User::class);
}
Note: U dont need UserWallet Model Since it is belongsTOMany Relationship
Suggestion: In real life example a user have many wallet and a wallet is only belongs to one user so the relation is HasMany(on to Many)
It should be plural. wallets and users
User Model:
public function wallets(): BelongsToMany //not wallet
{
return $this->belongsToMany(Wallet::class);
}
Wallet model:
public function users(): BelongsToMany //not user
{
return $this->belongsToMany(User::class);
}

Eloquent - How to match data between tables of a single ID

Having multiple tables with data that relates to each other, i'm trying to display that data in a view using Laravel.
I must be confused with how Laravel runs its queries and I need help to sort how to do, what in PHP&SQL would be a left join.
My Asset Model:
public function category(){
return $this->hasOne(Category::class);
}
My Category Model:
public function asset()
{
return $this->belongsTo(Asset::class);
}
My Country Model:
public function country()
{
return $this->belongsTo(Asset::class);
}
And my AssetsController:
public function asset($id)
{
$asset = Asset::find($id);
return view('admin.assets.asset')->with('assets', $asset);
}
And the Router:
Route::get('/admin/assets/asset/{id}', [
'uses' => 'AssetsController#asset',
'as' => 'assets.asset'
//Show the Asset
]);
And the View:
<p><strong>Price:</strong>{{$assets->price}} €</p>
<p><strong>Description:</strong>{{$assets->description}}</p>
<p><strong>Country:</strong>{{$assets->country}}</p>
<p><strong>Category:</strong>{{$assets->name}}</p>
So in the 'asset.blade.php' I get the id from a previous index.blade.php that has a list of all the assets. I want to get via the ID, an asset page that displays the category name and the country name, instead of the ID that belongs to the Asset table.
So it should echo something like $assets->country->country_name and $assets->category->name
dd($asset);
EDIT: Additional information about migrations
categories_table migration
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('url');
$table->timestamps();
});
}
assets_table migration:
public function up()
{
Schema::create('assets', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->double('price',15,2);
$table->mediumText('description');
$table->integer('country');
$table->integer('category');
$table->integer('subcategory');
$table->integer('subsubcategory');
$table->integer('broker');
$table->string('featured');
$table->string('slug');
$table->timestamps();
});
}
Got it working.
class Category
{
public function asset()
{
return $this->hasMany(Asset::class);
}
}
class Asset
{
public function category()
{
return $this->belongsTo(Category::class);
}
}
use App\Asset;
use App\Category;
use App\Country;
use App\Subcategory;
use Illuminate\Http\Request;
class AssetController extends Controller
{
public function asset($id)
{
$asset = Asset::find($id);
return view('admin.assets.asset')
->with('asset', $asset)
->with('category', Category::all())
->with('subcategory', Subcategory::all())
->with('country', Country::all());
}
}
The other models have the same relationship towards the Asset model and vice-versa.
The View:
<p><strong>Category:</strong>{{$asset->category->name}}</p>
<p><strong>Sub-Category:</strong>{{$asset->subcategory->name}}</p>
It now shows the name matching the id of the corresponding tables.

Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation

Trying to get a list of users associated with an event. Here are my eloquent models:
User.php:
public function fbevents()
{
$this->belongsToMany('Fbevent', 'fbevent_user');
}
Fbevent.php:
public function users()
{
$this->belongsToMany('User', 'fbevent_user);
}
I get this error when I try to find the list:
$event = Fbevent::find(10);
var_dump($event->users->lists('userId'));
I've set up a pivot table in the db with the following migration:
$table->increments('id');
$table->integer('fbevent_id')->unsigned()->index();
$table->foreign('fbevent_id')->references('id')->on('fbevents')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
And added an entry in the fbevent_user table with fbevent_id = 10 and user_id = 1.
You need to return a result from your relations
public function fbevents()
{
return $this->belongsToMany('Fbevent', 'fbevent_user');
}
public function users()
{
return $this->belongsToMany('User', 'fbevent_user');
}

Laravel - Many to many not pulling back results

I have a User class with the following:
public function school()
{
return $this->belongsToMany('School');
}
I have a School class with the following:
public function user()
{
return $this->belongsToMany('User');
}
I create my pivot table use the pivot generator, here is the migrate for it:
public function up()
{
Schema::create('school_user', function(Blueprint $table) {
$table->increments('id');
$table->integer('school_id')->unsigned()->index();
$table->foreign('school_id')->references('id')->on('schools')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->boolean('admin');
$table->timestamps();
});
}
There is only one item in the user table, the school table, and the pivot table. When I do
$user = User::where('email', '=', Input::get('email'))->first();
$schools = $user->schools;
return Response::json([
'success' => true,
'user' => $user->toArray(),
'schools' => $schools
]);
It returns a null for the schools. Am I missing something?
You have declared:
public function school()
{
return $this->belongsToMany('School');
}
But using $user->schools, you should change the function declaration to schools:
public function schools()
{
//...
}
Also make sure that, you are using the right relationship, I'm confussed because one user may belongs to only one school (logically).

Resources