LARAVEL: One-to-one relationship on a pivot table? - laravel

I can't think of how to handle this in Eloquent. I have a many-to-many relationship that needs a one-to-one relationship assigned to it.
Here is the basic database structure I designed in its simplest form:
ACCOUNTS: id
AGENTS: id
FEES: id
ACCOUNT_AGENT: account_id, agent_id, fee_id
Each Account belongsToMany Agents.
Each Agent belongsToMany Accounts.
Each "Account_Agent" (the many-to-many pivot table) belongsTo Fee.
How do I define that third relationship in an Eloquent model?
I want to be able to access the "account_agent" fee like this (or similar):
$account = Account::first();
foreach ($account->agents as $agent) {
echo $agent->fee;
}
Thanks, hopefully my question is clear.

See here:
https://laravel.com/docs/5.4/eloquent-relationships#many-to-many
Scroll down to Defining Custom Intermediate Table Models
Basically what you have to do is to define a class like this:
class AccountAgent extends Illuminate\Database\Eloquent\Relations\Pivot
{
/**
* Many:1 relationship with Fee model
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function fee()
{
return $this->belongsTo(Fee::class);
}
}
Then you define your many:many relationship in your Account class like this:
/**
* The agents that belong to the account.
*/
public function agents()
{
return $this->belongsToMany(Agent::class)->using(AccountAgent::class);
}
Then in your code, instead of this:
foreach ($account->agents as $agent) {
echo $agent->fee;
}
... do this:
foreach ($account->agents as $agent) {
/** #var Fee $fee_object */
$fee_object = $agent->pivot->fee;
}
In that loop $fee_object is of class Fee (the model class that covers the fees table) so you could echo $fee_object->fee_amount or whatever other columns you need to use.

Related

How get users from section table ? laravel

The idea is that I have relation between two table's section and user
the section_id exist in users table it relation with id section
SO for ex : section_id = 2 > want to bring all users belongs to id section
My code here use id from url and I don't want to do this I want without id bring all users :
public function getAllUsers($id)
{
$data = User::where('section_id',$id)->get();
}
If I'm understanding you correctly, you want to get all the users for a particular Section that have the relationship to that section.
Assuming you have the relationship set up correctly on the Section model:
public function users() {
return $this->hasMany('App\User');
}
I suggest you go about this 'backward' and just pull the users from the Section model itself (eager loading allows one query):
$section = Section::with('users')->first();
$usersForThisSection = $section->users;
If you setup a One to Many relationship you can say things like: $user->section to return the section a user belongs to...and $section->users to get a collection of all the users in a section -- the getAllUsers() is redundant in this case.
Make sure your User and Section models contain these methods. Sounds like your migration was setup properly if you have a section_id column on your users table.
More info on one-to-many here: https://laravel.com/docs/5.8/eloquent-relationships#one-to-many
// app/User.php
class User extends Model
{
public function section() {
return $this->belongsTo('App\Section');
}
}
// app/Section.php
class Section extends Model
{
public function users() {
return $this->hasMany('App\User');
}
}
Test out your relationships in php artisan tinker like so...
$user = User::find(1);
$user->section
$section = Section::find(1);
$section->users
you need a unique identifier to receive section_id's users. receive it from url(get) or ajax(post) . if you worry about users access then use "auth"

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());

Storing model names on database and retrieving the data

I am using laravel 5.2 and I am making a web site which requires to have locations on different category. I want to store model name in the database and fetch using the value retrieved from the database.
I have a hotel model
-id
-name
And I have restaurant model
-id
-name
And i have location model
-id
-name
-latitude
-longitude
-modal_name
I want to store App\Hotel in modal_name column and want to fetch data from the same model.
How do I go about solving this problem?
The only way I know is to use polymorphic relation.
You should add to your locations table 2 fields ( 1 for the model name and 1 for the id key on that model ) and the naming convention is usually ****able_type and ***able_id
for instance: locationable_type and locationable_id.
than on your location model add the following relation
class Location extends Model
{
/**
* Get all of the owning locationable models.
*/
public function locationable()
{
return $this->morphTo();
}
}
than on your hotel model add this relation
class Hotel extends Model
{
/**
* Get the hotel location.
*/
public function location()
{
return $this->morphMany('App\Location', 'locationable');
}
}
same thing for your restaurant model
class Restaurant extends Model
{
/**
* Get the restaurant location.
*/
public function location()
{
return $this->morphMany('App\Location', 'locationable');
}
}
than to use it you simply can use:
$hotel = App\Hotel::find(1);
dd($hotel->location);
for more information you can checkout laravel documentation
Good luck :)

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.

How to perform a has many through statement using laravel eloquent?

Say i have three tables users,users_groups and groups.How can i get the user's groups through the users_groups table?
class User extends Eloquent {
protected $table = 'users';
}
class Groups extends Eloquent {
protected $table = 'groups';
}
class Usergroups extends Eloquent {
protected $table = 'users_groups';
}
As per your request, I've put together a simple example for your specific use case:
The Tables:
Eloquent suggests creating 3 database tables in such a scenario: users, groups and group_user.
The Laravel documentation states that:
The group_user table's name is derived from the aplhabetical order of the related model names.
The group_user table should contain the columns user_id and group_id which will contain the primary keys of group and user entries. The group_user table is what's known as a pivot table.
This conforms to 3NF (if you're interested).
The Models:
The User model should contain the following code:
<?php
class User extends Eloquent {
//...Other code…
public function groups()
{
return $this->belongsToMany('Group');
}
}
The Group model should contain the following code:
<?php
class Group extends Eloquent {
//...Other code…
public function users()
{
return $this->belongsToMany('User');
}
//...Other code…
}
You do not need a UserGroup model as found in your question.
Usage:
In order to retrieve all groups to which a particular user belongs you would do the following:
$user = User::find($user_id);
$user_groups = $user->groups();
Similarly in order to retrieve all users belonging to a particular group you would do the following:
$group = Group::find($group_id);
$group_users = $group->users();
In order to add/remove a user to a group would would do the following:
$user = User::find($user_id);
//Add a user
$user->groups()->attach($group_id);
//Detach a user
$user->groups()->detach($group_id);
Other:
You should read more in the Laravel docs about pivot tables here and about defining foreign keys (for your pivot table) in your migrations here.
I hope that helps!

Resources