Laravel 5 custom user Auth methods - php

My authenticated user has a color assigned to them via a relationship in the User model.
I would like to go:
return Auth::color()->id;
To return the logged in users color id.
How do I go about doing this?
I also can't do:
Auth::user()->color()->id
or
Auth::user()->color->id
I am getting Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$id
However all relationships are defined.
I am coming from Laravel 4, what am I doing wrong?
<?php
namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword;
protected $table = 'users';
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
public function color() {
return $this->hasOne('\App\Models\Colour');
}
public function salesarea() {
return $this->belongsTo('\App\Models\Salesarea');
}
public function getNameAttribute() {
return $this->first_name." ".$this->last_name;
}
}

Seeing i cant create a comment yet i'll write my question here,
Is this suposed to be a one to many or one to one ?
Is the user_id column present in your color database table ?
if it is a one to many you need to check if:
your user model has this function
public function colors()
{
return $this->hasMany('App\Color');
}
your Color model has this function
public function user()
{
return $this->belongsTo('App\User');
}
If so you should be able to do
Auth::user()->colors witch is a collection of color objects
if it is supposed to be a one to one
you need to check if your user model has this function
public function color()
{
return $this->hasOne('App\Color');
}
your color model has this function
public function user()
{
return $this->belongsTo('App\User');
}
If so you should be able to do
Auth::user()->color witch is a color object

If your user table has a color_id column, then you want a belongs to relation, not a has one. A has one relation is where the other table would have a user_id column (say a profiles table where a profile can only belong to one user). But in your case, I’m assuming a color could be assigned to many users, therefore a user belongs to a color, and a color has many users.
So in this case, you need to change your relationship:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function color()
{
return $this->belongsTo(Color::class);
}
}
You will then be able to query the color from the authentication services:
$color = Auth::user()->color;
Also keep an eye on your model naming, as you used both the American and British English spellings of ‘color’ in your question.

Related

How to attach a relationship directly on an object?

I don't know if I formulated the question correctly, but whatever.
So when I use the "store" method on my controller, I send two fields, "name" and "fr", both in the same request.
In my controller, I want to be able to create my Model (Room) and attach its relationship to it (RoomTranslation). When I try the following code, it tells me I didn't provide the room_id. Is there an automatic way to achieve this ?
public function store(RoomRequest $request)
{
$request = $request->validated();
$room = new Room;
$room->create($request);
$room->translations()->create($request);
return success('');
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class RoomTranslation extends Model
{
protected $fillable = ['fr', 'room_id'];
public function room() {
return $this->belongsTo('App\Room');
}
}
<?php
namespace App;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
use App\RoomTranslation;
class Room extends Model
{
protected $fillable = ['name'];
public function categories() {
return $this->hasMany('App\Category');
}
public function translations() {
return $this->hasOne('App\RoomTranslation');
}
}
Thank you for your help !
P.S. : If there is a cleaner way to write this part of my code, I will be happy to hear how I can improve it.
Thank you !
You can do this:
Room::create($request->only(['name']))->translations()->create($request->only(['fr']));
just look for typo or input names to be correct.
Also in Room model class translations relation if you have multiple languages for every Room should be hasMany, And if you don't have many translations per Room you could just add a column for translation language.

Laravel Eloquent: hasManyThrough Many to Many relationship

I have the following classes (simplified here) in my Laravel 5.7 model:
VEHICLE.PHP
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Vehicle extends Model
{
public function journeys()
{
return $this->hasMany('App\Journey');
}
}
JOURNEY PHP
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Journey extends Model
{
public function vehicle()
{
return $this->belongsTo('App\Vehicle');
}
public function users()
{
return $this->belongsToMany('App\User');
}
}
USER.PHP
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function journeys()
{
return $this->belongsToMany('App\Journey');
}
}
I have an intermediate table (journey_user) between users and journeys (see schema attached).
I can easily get all journeys made by a particular user. But how can I get all vehicles used by a particular user? The standard hasManyThrough method does not appear to work because of the Many to Many relationship between users and journeys.
Thanks for your help!
I haven't tested this out. However, it should be possible to get all vehicles by looping through all the user's journeys, creating an array of vehicles and return this as a collection.
This can be added to your User.php model controller:
/**
* Get all vehicles which user has used
*
*/
public function vehicles()
{
$vehicles = [];
$this->journeys()
->each(function ($journey, $key) use (&$vehicles) {
$vehicles[] = $journey->vehicle;
});
return collect($vehicles);
}
Here, we create an empty array. Then we loop through all the journeys of the users (passing the $vehicles array as a reference to update it).
We use the each() collection method to loop through each journey. We create a new entry to the $vehicles array, adding the vehicle.
Finally, we return all vehicles as a collection.
We can use this in our application like so:
User::find($id)->vehicles();
Note: You could return this as an accessor attribute by changing the function name to setVehiclesAttribute(). This will allow you to access the vehicle field like User::find($id)->vehicle.

Simple way to compare manytomany relationships? Laravel 5.3

I have a set of relationships that looks like this:
The users and agencies have a lot of data stored in them, in addition to the pivot tables you see there.
What I'd like to do is find the agencies or users that match the preferences of the currently logged in individual, whether they are an agency or user.
It's a straight comparison, so nothing fancy. But I honestly have no idea how to write the eloquent query to account for the pivot tables. Can someone point me in the right direction?
I'm looking at something like this, which is understandably failing:
$loggedinagency = Auth::user()->id;
$match_user_agency = User::with('work_prefs')
->where('work_prefs', 'like',
Agency::find($loggedinagency)->work_prefs)
->get();
Edit: The relationships are declared like so:
User:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
protected $table = 'users';
public function work_prefs() {
return $this->belongsToMany('App\Work_Prefs', 'preference_user', 'user_id', 'preference_id');
}
}
Agency:
<?php
namespace App;
class Agency extends Authenticatable
{
use Notifiable;
protected $table='agencies';
public function work_prefs() {
return $this->belongsToMany('App\Work_Prefs', 'agency_preference', 'agency_id', 'preference_id');
}
}
Work Preferences:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Work_Prefs extends Model
{
protected $table = 'work_prefs';
public function user() {
return $this->belongsToMany('App\User', 'preference_user', 'preference_id', 'user_id');
}
public function agency() {
return $this->belongsToMany('App\Agency', 'agency_preference', 'preference_id', 'agency_id');
}
}

Class 'phone ' not found while implementing eloquent relationship

This is the first time i am trying to use eloquent relationship.I have a userModel and a phoneModel class.They represents users and phone table respectively. Here i am trying to access The phone number of a user when he/she logged in.
users table has the field (id,name,password) and phone table has the
(field id,phone_no,user_id)
phone migration is below:
public function up()
{
//
Schema::create('phone',function(Blueprint $table){
$table->increments('id');
$table->string('phone_no',20);
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
i applied hasOne and belongs to relationship on both models:
userModel.php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable;
class userModel extends Model implements Authenticatable
{
//
use \Illuminate\Auth\Authenticatable;
protected $table = 'users';
public function phone(){
$this->hasOne('App\Models\phone');
}
}
phoneModel.php:
namespace App;
use Illuminate\Database\Eloquent\Model;
class phoneModel extends Model
{
//
protected $table='phone';
public function user()
{
return $this->belongsTo('users');
}
}
Now when i tried to get a phone number from logged user i get an error called class 'phone' not found
Here is the code inside show method of userController:
public function show($user)
{
//
$indicator=is_numeric($user)?'id':'name';
$info=userModel::where($indicator,'=',$user)->get()->first();
if($info){
$phone = userModel::find($info->id)->phone;
$data=array('info'=>$info,'phone'=>$phone);
return View::make('user.show')->with($data);
}else{
$info=userModel::where($indicator,'=', Auth::user()->name)->get()->first();
return View::make('user.show')->with('user',$info);
}
}
You named your phone class phoneModel but you added the relationship as $this->hasOne('App\Models\phone');. You also created those classes in the App namespace but referenced them as App\Models\class.
The standard practice is to name your model classes after the model and using uppercase letters. So your classes would be called User and Phone rather than userModel and phoneModel. And the database tables would be users and phones. If you use these standards, Laravel will take care of a lot of things automatically behind the scenes.
User class
namespace App;
class User extends Model implements Authenticatable
{
//
use \Illuminate\Auth\Authenticatable;
//Laravel will assume the User model is in the table `users` so you don't need to specify
public function phone(){
$this->hasOne('App\Phone');
}
Phone Class
namespace App;
class Phone extends Model
{
//Laravel will assume the Phone model is in the table `phones` so you don't need to specify
public function user()
{
return $this->belongsTo('App\User');
}

Laravel 5 check role giving error "trying to get property of non object"

I am very new to Laravel and am trying to implement roles to users.
I have created the Role table and Model associated with it
I have added a column role to the users table.
I am now trying to check that role in the User model
EDIT: After an answer/explanation here I changed role to role_id in the users table but I am still getting the same error.
Here is my User Model...
<?php namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Auth;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
// more stuff
public function role()
{
return $this->belongsTo('App\Role');
}
public function isAdmin()
{
return $this->role->slug == 'admin';
}
}
And my Role Model
<?php namespace App;
use Illuminate\Database\Eloquent\Model as Eloquent;
class Role extends Eloquent {
protected $table = 'roles';
public function users()
{
return $this->hasMany('App\User');
}
}
When I go to my admin page I have the following function...
public function index(User $user)
{
if ($user->isAdmin()) {
return view('admin/home_admin');
}
else {
return redirect('home');
}
}
However Im getting the error...
Trying to get property of non-object in User.php line 62 at
HandleExceptions->handleError('8', 'Trying to get property of
non-object', '/home/vagrant/Code/esearch/app/User.php', '62', array())
in User.php line 62
I have tried this while logged in and not logged in with the correct role. Am I missing something obvious here?
The problem with the code started off with the role_id setting that #user3158900 noticed. This was something that needed to be resolved.
But you were using the improper form of user when attempting to see what is happening. Instead of the User $user you need Guard $user or Guard $auth as it is more commonly seen. You can also use Auth::user()->isAdmin().
There is one last thing that should be looked at that I did not mention in my comment above.
If the user is not logged in and is a guest you will get an error trying to find Auth::user() and it will fail. This is because Auth::user() is null when you are a guest. So you should do a check that is logged in.
You can either use !Auth::guest() or Auth:check() (which is cleaner).
Hopefully this is all good for you!
You are close. Laravel assumes the foreign key for role to be role_id but since you are using role, you need to set that up in your relation as well.
In your Role model.
public function users()
{
return $this->hasMany('App\User', 'role');
}
In your User model.
public function role()
{
return $this->belongsTo('App\Role', 'role');
}
Because role would both be a relating function and a column in your table, it would be best to modify the column name to role_id to match what Laravel expects.

Categories