Laravel: Multiple tables in one model - laravel

I have the following model for Users:
class User extends Authenticatable
{
use Notifiable;
protected $table = 'login_info';
/**
* 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 getDashboards()
{
return \DB::table('dashboard')
->select('type')
->where('id', Auth::id())
->orderBy('column', 'asc')
->get();
}
}
Users have different information in many tables
user info like name, office, dashboard,2FA etc
Is the way I do it now "best practice" (like the getDashboards function) for getting information from different tables?
Or should I create a model for each of the tables and then "join them" (hasMany, belongsToMany, and so on) for each of the tables?
EDIT:
I am now using models, but the result of the query is always an empty array.
class Dashboard extends Model
{
protected $table = 'dashboard';
public function user()
{
return $this->belongsTo(User::class,'user_id','id');
//user_id
}
}
user_id is the id of the user which is used in the login_info table.
And in the User class I have:
public function dashboards()
{
return $this->hasMany(Dashboard::class,'id','user_id');
}
In the login controller I have:
$user = \App\User::find(1);
$user->dashboards;
Anyone see what the problem could be?
Thanks for any help!

public function dashboards()
{return $this->hasMany(\App\Dashboard::class);
}
And in your Dashboard Model you do it this way
protected $casts = [
'user_id' => 'int',
];
public function user()
{
return $this->belongsTo(\App\User::class);
}

The more Laravel way is to rather created the related Dashboard model and use the eloquent relationships, and harness the features of the ORM. Nothing wrong to include an orderBy on the relationship if you always need ordering on that column.
class User extends Authenticatable
{
public function dashboards()
{
return $this->hasMany(Dashboard::class)
->orderBy('column', 'asc');
}
}
class Dashboard extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}

You do not have to do anything in the model! Just refer to the model in the controller, for example:
User::where('id', Auth::id())->pluck('type');

Related

Problem with laravel relationships (many to many + one to many), cant access them for some reason

so, i have this database
one "user" has many "inputs" and "input" has only one "habitos" and "sentimentos", so we can say that one user has many "habitos", and "sentimentos" too.
and i should be able to do something like {{$user->inputs->habitos}}, but for some reason i can't, and somehow {{$users->input}} works and {{$input->habitos}} also works, here is the code
user model:
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'telefone',
'hotmart_id'
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function input(){
return $this->hasmany(Input::class, 'user_id', 'id');
}
}
input model:
class Input extends Model
{
use HasFactory;
public function habito(){
return $this->belongsto(Habito::class, 'habito_id', 'id');
}
public function sentimento(){
return $this->belongsto(Sentimento::class, 'sentimento_id', 'id');
}
public function user(){
return $this->belongsto(User::class, 'user_id', 'id');
}
}
habito model:
class Habito extends Model
{
use HasFactory;
protected $fillable = ['nome', 'categoria'];
public function input(){
return $this->hasmany(Input::class, 'habito_id', 'id');
}
}
i've been searching for someone with the same problem, but i cant seem to find nothing on this, thanks in advance :).
I had the same issue, well.. almost the same.
I had Meals that has a pivot table with tags - so it's a many to many relationship and tags have a translation.
Picture this, when fetching the data and you use a query "with=tags", you actually fetch tagtranslations based on the Locale (en, de, fr, etc.), so you go through "meal_tag" pivot table, through "tag" table and finally you get to "tagtranslations" and fetch translations of the tag_id connected to the meal.
I don't think you have to use has
This is how I did it:
Meal Class:
public function tags(){
return $this->belongsToMany(Tag::class, 'meal_tags')->withTrashed();
}
MealTag class:
public function meals()
{
$this->hasMany(Meal::class, 'meal_id')->withTrashed();
}
public function tags()
{
$this->hasMany(Tag::class, 'tag_id')->withTrashed();
}
Tag class:
public function meals()
{
return $this->belongsToMany(Meal::class, 'meal_tags')->withTrashed();
}
public function translations()
{
return $this->hasOne(TagTranslation::class)->where('locale', app()->getLocale())->withTrashed();
}
**ignore the middleware for translations because you don't need it, just use withTrashed if you use softDeletes
and finally TagTranslations class:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
class TagTranslation extends Model
{
use HasFactory, SoftDeletes, HasRelationships;
public function tag(){
return $this->belongsTo(Tag::class)->withTrashed();
}
public function meals(){
return $this->hasManyDeep(Meal::class, [Tag::class, 'tag_id','meal_id'])->withTrashed;
}
}
notice I'm using hasManyDeep, for that you have to install staudenmeir package:
Click here to view on github
.. but the thing is, Eloquent should recognize everything you need even without hasManyDeep, but if it works like that, who am I to argue :D
this worked for me - if something goes wrong I'm sure it's just a matter of some slight adjustment.

How to get value from child table using eloquent in Laravel?

I have two table : users and profile.
A user may have one or multiple profile. I want to access the combined data of both table: 'ID' in user table is foreign key in profile table
User model :
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'first_name','last_name', 'email', 'password','phone','user_type',
];
protected $hidden = [
'password', 'remember_token',
];
public function profile()
{
return $this->hasMany(profile::class);
}
}
Profile model is :
class profile extends Model
{
protected $fillable = [
'id','relationship_status','dob','height',
'weight','primary_language'
];
protected $primaryKey = 'profile_id';
public function User()
{
return $this->belongsTo(User::class,'id','id');
}
}
Change your user model profile relationship like this
User Model
public function profile()
{
return $this->hasOne(Profile::class); //assuming your user has single profile
}
Profile model
class Profile extends Model
{
protected $fillable = [
'id', 'user_id', 'relationship_status','dob','height',
'weight','primary_language'
];
//add user_id field in profiles table
//protected $primaryKey = 'profile_id'; //no need of this, because you have id field in profiles table
public function user()
{
return $this->belongsTo(User::class);
}
}
after that you can fetch data like this
$user = User::find(2);
dd($user);
dd($user->profile)
When fetching multiple users details, then use eager loading
$users = User::with('profile')->get();
foreach($users as $user){
dd($user->profile)
}
Check details https://laravel.com/docs/5.6/eloquent-relationships#one-to-one

Displaying users with 2 related tables records

I have 3 Models :
User, Role and Branch.
They are related like this :
Pour User model :
class User extends Model
{
// Define fields to be fillable
protected $fillable = [
'firstname',
'lastname',
'telephone',
'address',
'password',
'code',
'status',
'branches_id',
'roles_id'
];
/**
* Get the role record associated with the user.
*/
public function role()
{
return $this->hasOne('App\Role');
}
/**
* Get the branch record associated with the user.
*/
public function branch()
{
return $this->hasOne('App\Branch');
}
}
For Role Model :
class Role extends Model
{
// Define fields to be fillable
protected $fillable = ['description'];
/**
* Get the user that owns the role.
*/
public function user()
{
return $this->belongsToMany('App\User');
}
}
For branch model :
class Branch extends Model
{
// Define fields to be fillable
protected $fillable = ['description', 'location'];
/**
* Get the user that owns the branch.
*/
public function user()
{
return $this->belongsToMany('App\User');
}
}
I know that if i was using Blade, to list user's roles, i could have done something like : $user->role()
But i am trying to use angular 2 for the frontend and laravel 5.3 for my backend.
My question is how to retrieve users along with roles and branches
Here is my index action in my UserController:
public function index()
{
// Get all users, along with roles and branches
$users = User::all();
// Send the response
return response()->json([
'users' => $users
], 200);
}
Use eager loading:
$users = User::with('role', 'branch')->get();
Also if user has one role and one branch, relationships should be belongsTo() instead of belongsToMany():
return $this->belongsTo('App\User');
You can use the with() method for this, e.g.
$users = User::with('role')->get();
See https://laravel.com/docs/5.4/eloquent-relationships#eager-loading for more information

hasOne and belongsTo relation tables - laravel

My tables :
users :
id fname email
brands:
id title user_id_made
each user has many brands and each brand belongTo an user.
class Brand extends Model
{
protected $table = 'brands';
protected $fillable = array('title_fa',
'title_en','logo','user_id_made');
public function user()
{
return $this->hasOne('App\Models\User');
}
}
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'fname' ,'lname' , 'username', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function brand()
{
return $this->belongsTo('App\Models\Brand','user_id_made');
}
}
my code hasn't any output about users .
$data['brands'] = \DB::table('brands')->find(1);
var_dump($data['brands']);
return;
This will not load user. I will suggest you to use model instance in place of DB instance. if you want to load user with brands then you can use laravel's eager loading.
First in your Brand.php model
You need to pass the second argument as user_id_made to hasOne function otherwise it will assume it user_id.
public function user()
{
return $this->hasOne('App\Models\User','user_id_made');
}
You can do something like that.
$data['brands'] = Brand::with('user')->find(1);
Now If you will return $data['brands'] then it will return user information also.
Hope this will help.

Eloquent Model has parent model

I have a Model called User with stuff like name, country and some relationships.
Now I want a Model, e.g. Vendor, having all the same functions and variables as a User including some More stuff
I thought I could to it this was:
class User extends Model implements AuthenticatableContract
{
use Authenticatable; SoftDeletes;
protected $dates = ['deleted_at', 'last_login'];
protected $fillable = [
'name',
'password',
'country',
];
protected $hidden = ['password'];
public function logs()
{
return $this->hasMany('App\Log');
}
}
And the Vendor Model:
class Vendor extends User
{
protected $fillable = [
'description'
];
public function user() {
return $this->belongsTo('App\User');
}
public function products()
{
return $this->hasMany('App\Product', 'vendor_id');
}
The Controller checks the role of the user and loads a user model or a vendor model:
if(Auth::user()->role > 1)
$user = Vendor::where('user_id', Auth::user()->id)->first();
else
$user = Auth::user();
return $user->load('logs');
But the load call fails for a vendor. I was able to join the fields of a user inside a vendor but I also need the functions of it.
The problem was that the logs function checks a field that doesn't exists.
Using this functions works:
public function logs()
{
return $this->hasMany('App\Log', 'user_id', get_called_class() !== get_class() ? 'user_id' : 'id');
}

Resources