Mapping of Eloquent models to tables? - laravel

We are able to create Eloquent models for tables. But how Laravel knows to which table to associate a model with? Do we have something similar to hbm.xml(mapping file we use for Hibernate) which says this model means this table.

The table name is a protected property:
class User extends Eloquent {
protected $table = 'my_users';
}
Laravel Docs

You can manually override the table name as the above answer states.
Its just a protected member of the Model.php class.
class User extends Eloquent {
protected $table = 'my_users';
}
Otherwise, a lowercase, plural format is automatically used, based on the classname of the Model. (class_basename($this))
As shown here... (Illuminate/Database/Eloquent/Model.php)
/**
* Get the table associated with the model.
*
* #return string
*/
public function getTable()
{
if (isset($this->table)) {
return $this->table;
}
return str_replace('\\', '', Str::snake(Str::plural(class_basename($this))));
}

Related

laravel eloquent migrations

In laravel eloquent relationship, is it still necessary to make migration even though there's an existing database? beginners here.
I create a one-to-one eloquent relationship inside my model to get the specific column from another table's record and fetch to the datatable, but it did not work.
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Directorystatus extends Model
{
use HasFactory;
protected $table = 'user_status';
protected $fillable = ['status_id' , 'status_xtitle'];
public function userbasic() {
return $this->belongsTo(directorybasic::class,'user_xusern','status_xuser');
}
}
class Directoryuser extends Model
{
use HasFactory;
protected $table = 'user_basic';
protected $primaryKey = 'user_id';
protected $fillable = ['user_id' , 'user_xusern' , 'user_xfirtname' ,'user_xmiddlename','user_xlastname'];
public function userstatus() {
return $this->hasOne(directorystatus::class,'user_xusern','status_xuser');
}
}
No. Migrations are not necessary. Defining relationships on both sides is also not necessary, if you don't need them both. (You can have only belongsTo, without having hasOne or hasMany in the opposite model.)
First, make sure you are using the right object (Directorystatus::class / Directoryuser:class - I see they're not capitalized in your code). The next param is the foreign key, meaning the column which points to a model's primary key. The third param is optional and is used only if the primary key is not id.
For example if you have a column status_xuser in the table user_status, which contains a user_id from user_basic table, you should define it like this:
public function userbasic() {
return $this->belongsTo(Directoryuser::class,'status_xuser','user_id');
}
And in order to use this relationship, when you retrieve a model from the db, for example, you should call on it the same way your relationship function is named.
$status = Directorystatus::find(1);
$user = $status->userbasic();
I would also suggest you name your classes in camelCase, because it's the accepted practice (in Laravel especially).

Laravel Eloquent relationship data retrieve

I have below code to get data from database,
$profile = Profiles::find(1);
$currency = Profiles::find($profile->currency_id)->currency;
Then created a relationship in the model as below,
class Profiles extends Model
{
use HasFactory;
protected $table = 'Profiles';
protected $primaryKey = 'profile_id';
public function Currency()
{
return $this->belongsTo(Currencies::class, 'currency_id');
}
}
class Currencies extends Model
{
use HasFactory;
protected $table = 'Currencies';
protected $primaryKey = 'currency_id';
public function profile()
{
return $this->hasOne(Profiles::class, 'currency_id');
}
}
Problem is that there is only 1 profile and 100 currency, currency_id is a foreign key in Profiles table,
I could not get data and get this error, Trying to get property 'currency' of non-object"
If i use $currency = Profiles::find(1)->currency; then it retrieve first row of Curriencies table which is not required data.
How can I get currency row for that specific profile?
The problem is that the find() method will look for the primaryKey and in your second call the currency_id is not the pk.
Two solution for you:
replace the find by a where clause like so: $currency = Profiles::where('currency_id',$profile->currency_id)->value('currency')
Or a more Laravel way to do it, through the relationship $currency = $profile->currency;

Clarification with eager loading/mutators/accessors for laravel

I'm making a laravel app for work and I need to load all users with their attached role without any nesting of the roles. I used this tutorial for roles: https://medium.com/#ezp127/laravel-5-4-native-user-authentication-role-authorization-3dbae4049c8a . If I use public $with = ['roles']; on my User model it returns the entire role object within the user object and I need it to just return role:'role_name';
/**
* set up eloquent between roles/user
*
* #return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function roles()
{
return $this->belongsToMany(Role::class);
}
Above is in my User model and below is in my Role model to define the relationships.
/**
* provides a many-to-many relationship to User model
*
* #return User::class
*/
public function users()
{
return $this->belongsToMany(User::class);
}
I thought that by adding this to the User model:
protected $appends = ['role_name'];
public function getRoleNameAttribute()
{
return $this->attribute['name'];
}
it would return everything but all it does is create a role_name: 'user_name'; On the model. So I guess I realize I'm accessing just the Users table and not the Roles table in the DB, but again not really sure what to do. Any help would be greatly appreciated.
If for the purpose of convenience you need to access the role name directly from the model you should refer to the actual relationship data:
protected $appends = ['role_name'];
public function getRoleNameAttribute()
{
return $this->roles->pluck('name');
}
This should append the array of role names to your user model. It will be an array because roles seem to have a many-to-many relationship with the User model.
The issue is you're returning $this->attributes['name'] in the getRoleNameAttribute. You want the role names, so instead you'd do something like this:
If you want an array with the names:
return $this->roles()->pluck('name')
If you want the names as a string:
return array_implode(", ", $this->roles()->pluck('name')->toArray());

laravel use field in Eloquent model from another table

I have a model named "User". I want "Password" field from Eloquent from another table, and when user calls the user::all() method, all selected fields from different tables come in the result.
How can i do that?
Results are not displayed in with() .
my problem solved by using $appends in Eloquent model .
my code :
class User extends Eloquent {
protected $table = 'user';
protected $attributes = ['password'];
protected $appends = ['password'];
public function getPasswordAttribute()
{
return $this->getPAsswordMethod();
}
}
Your question is extremely board and borderline unanswerable but I will give you a board solution.
You are able to establish relationships to other tables via the Model objects you create. Lets pretend you have a Password table which belongs to the User.
User model:
public function password()
{
return $this->hasOne(Password::class, 'FK', 'PK');
}
You can now do User::with('password')->get(['FieldName']); and this will give you all of the passwords which have the above relationship to a user.

laravel4 How can i use eloquent in my controller?

I would like to create a relationship between 2 tables with eloquent but i can't find exactly how to proceed...
Here are my 2 models with relationship :
Table "etablissement":
<?php class Etablissement extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'etablissement';
public function annulation()
{
return $this->hasMany('Annulation');
}}
Table "annulation":
<?php class Annulation extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'annulation_remboursement';
public function etablissement ()
{
return $this->belongsTo('Etablissement');
}}
In the "Etablissement" table there is an id for each etablissement (id_etablissement) and in the "annulation" there is a column with the id_etablissement. How can i return in my controller a relation in order to have the etablissement's name with the annulation->id_etablissement :
class AnnulationsController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
}
It should be something like this within your index method:
$annulation = Annulation::find(1);
$annulation->etablissement->name
The annulation_remboursement table should have a establissement_id field.
Perhaps the error may be in the keys of the relation.
In https://laravel.com/docs/4.2/eloquent#one-to-one we see:
Take note that Eloquent assumes the foreign key of the relationship based on the model name. In this case, Phone model is assumed to use a user_id foreign key. If you wish to override this convention, you may pass a second argument to the hasOne method. Furthermore, you may pass a third argument to the method to specify which local column that should be used for the association:
return $this->hasOne('Phone', 'foreign_key');
return $this->hasOne('Phone', 'foreign_key', 'local_key');
[...] One To Many: Again, you may override the conventional foreign key by passing a second argument to the hasMany method. And, like the hasOne relation, the local column may also be specified:
return $this->hasMany('Comment', 'foreign_key');
return $this->hasMany('Comment', 'foreign_key', 'local_key');
* You should also checkout Defining The Inverse Of A Relation at the same page.
So, in your case you have a key named id_etablissement but Laravel is searching for etablissement_id. If you wish to override this behaviour and specify a key you should do something like:
protected $table = 'etablissement';
public function annulation()
{
return $this->hasMany('Annulation','id_etablissement');
}
and according to "The Inverse Of A Relation"
protected $table = 'annulation_remboursement';
public function etablissement ()
{
return $this->belongsTo('Etablissement','id_etablissement');
}
Note that I didn't put any of the local keys, but those will be the third parameter of the relation.

Resources