Consider the following world model:
A User can be member of zero or more UserGroups
A UserGroup can have zero or more User members
A Repo can reside in zero or more RepoGroups
A RepoGroup can contain zero or more Repos
A UserGroup can be granted 'read' or 'write' access to a RepoGroup
The (simplified) database schema implementing this model looks like this:
Setting up the Eloquent many-to-many relationship between User and UserGroup via the user_group_pivot table is straight forward, as is the equivalent relationship between Repo and RepoGroup. The access_rights table is a pivot table with additional access information, but the relationship between ClientGroup and RepoGroup is also many-to-many, and equally straight forward. Now the following challenges remain:
The relationship between UserGroup and Repo
The relationship between RepoGroup and User
The relationship between User and Repo
This is the code I've got so far:
class User extends Model {
public function userGroups() {
return $this->belongsToMany(UserGroup::class, 'user_group_pivot');
}
public function repos() {
# Eloquent wizard can makez magic here?
}
public function repoGroups() {
# Eloquent wizard can makez magic here?
}
}
class UserGroup extends Model {
public function users() {
return $this->belongsToMany(User::class, 'user_group_pivot');
}
public function repos() {
# Eloquent wizard can makez magic here?
}
public function repoGroups() {
return $this->belongsToMany(RepoGroup::class, 'access_rights')
->withPivot(['access']);
}
}
class RepoGroup extends Model {
public function repos() {
return $this->belongsToMany(Repo::class, 'repo_group_pivot');
}
public function users() {
# Eloquent wizard can makez magic here?
}
public function userGroups() {
return $this->belongsToMany(UserGroup::class, 'access_rights')
->withPivot(['access']);
}
}
class Repo extends Model {
public function repoGroups() {
return $this->belongsToMany(RepoGroup::class, 'repo_group_pivot');
}
public function repos() {
# Eloquent wizard can makez magic here?
}
public function repoGroups() {
# Eloquent wizard can makez magic here?
}
}
I've scoured the web looking for examples similar to this, but they either blatantly plagiarize the Laravel docs or are equally trivial. I've been playing around with the Model::hasManyThrough() relationship, but to no avail. Hence I put my hopes in the Eloquent wizards of the world. I can haz helps, pliis?
There is a possibility to go to repos without touching other relations.
You can add code like this below to User::repos
$repos = [];
foreach($user->userGroups() as $userGroup){
foreach($userGroup->repoGroups() as $repoGroup){
foreach($repoGroup->repos() as $repo){
$repos[] = $repo;
}
}
If you are worried about performence (example during processing a lot of users) you can use eager loading during fetch users with repos from DB
$users = App\User::with(['userGroups.repoGroups.repos'])->get();
Related
I have a little problem,
i can't see how can i make a three table relation on Laravel.
DELETED
If someone can help me, I take notes !
Thanks !
As far as I can see, you need to create a relationship to your pivot table and then, you can create relationships to both table.
class Contact extends Model
{
public function filmJobs()
{
return $this->hasMany(ContactFilm::class);
}
}
class ContactFilm extends Model
{
public function film()
{
return $this->hasOne(Film::class);
}
public function job()
{
return $this->hasOne(Job::class);
}
}
You can now use it like that: $contact->filmJobs[0]->film and $contact->filmJobs[0]->job.
Using Laravel 5.4 and the VentureCraft/revisionable package.
I have 3 models: User, Company and Order.
The Order model implements the Revisionable trait:
namespace App\Models;
class Order extends Eloquent {
use \Venturecraft\Revisionable\RevisionableTrait;
// ...
}
The User model has a relationship with the Company model:
public function company() {
return $this->belongsTo('App\Models\Company');
}
And I would like to eager load the company of a user from an order revision. Something like this
$order = Order::with('revisionHistory.user.company')->find(1);
foreach($order->revisionHistory as $revision) {
$company = $revision->user->company;
}
I've tried overwriting various methods (e.g. revisionHistory and identifiableName) from the Revisionable trait without any luck.
You can use $company = $revision->userResponsible()->company to get company of the User that change the Order.
I think this is not possible with the current version of the package.
The reason behind is that userResponsible() is not an actual relationship, it's just a function that returns an instance of the User model.
To allow eager loading, something like this would be needed:
public function userResponsible()
{
if (class_exists($class = '\Cartalyst\Sentry\Facades\Laravel\Sentry')) {
return $this->belongsTo(Config::get('sentry::users')['model'], 'user_id');
} else if (class_exists($class = '\Cartalyst\Sentinel\Laravel\Facades\Sentinel')) {
return $this->belongsTo(Config::get('sentinel::users')['model'], 'user_id');
} else {
return $this->belongsTo(Config::get('auth.model'), 'user_id');
}
}
Then you would be able to eager load like this:
$order = Order::with('revisionHistory.userResponsible.company')->find(1);
You can view the original issue in GitHub.
I have a Laravel project and I'm using Eloquent for models.
Let's say I have three related tables:
User
Demographics
Roles
I would like my User model to inherit both Demographics and Roles based on Foreign Key as a one-to-one relation.
I am just looking for some feedback on what might be the most efficient / elegant / safest / performant / cleanest way to accomplish this.
So you're just looking for basic relations and eager loading those relations.
Try this:
class User extends Model
{
public function demographic()
{
return $this->hasOne('App\Demographic');
}
public function role()
{
return $this->hasOne('App\Role');
}
}
class Demographic extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
class Role extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
Then to access the User with all relations:
$user = User::with(['demographic', 'role'])->find(1);
var_dump($user->demographic); // returns the related Demographic model
var_dump($user->role); // returns the related Role model
I have a pivot table of users_operators.
I want to grab the operator_id of the user.
This is how i do this now, but its seems like verbose way.
if (Auth::user()->type === 'operator') {
$user = Auth::user();
// There is a better way to do this?
$operator_id = $user->operator[0]['pivot']['operator_id'];
Session::put('operatorId', $operator_id);
}
class Operator extends \Eloquent
{
public function users() {
return $this->belongsToMany('User');
}
}
class User extends \Eloquent
{
public function operator() {
return $this->belongsToMany('Operator');
}
}
I'm, battling insomnia and not functioning at 100%, but you should be able to get away with $user->operator->id based on what I'm interpreting your models to be (it looks like you had a typo when you copied them into the question).
If that doesn't work, you might want to check out the "Dynamic Properties" section in the Eloquent docs for more info, if you haven't already.
I'm a real newbie to Laravel but I'm loving it so far. I'm struggling on thing however, I want to retrieve the data for the user that is logged in and I am not sure how to go about this.
I have a few tables but I'll keep it basic for now, I have projects table and a users table, I've defined the relationships between these two in the models as so:
user.php
public function projects() {
return hasMany('project');
}
project.php
<?php
use Illuminate\Database\Eloquent\ModelNotFoundException;
class Project extends Eloquent
{
public function user()
{
return belongsTo('user');
}
}
I know I can do the following to retrieve all projects in the database with a foreach loop, however this doesn't retrieve the logged in users projects:
$projects = DB::table('projects')->get();
I saw one tutorial which wasn't very in depth but he said to access the model query I would have to use the following command:
$project = User::all()->projects;
However this hasn't worked either. Can anyone point me into the right direction with real tutorials or post simple examples?
Thanks in advance
Those are the projects of your logged in user:
if (Auth::check())
{
$projects = Auth::user()->projects;
}
And this must be in your relation:
class User extends Eloquent
{
public function projects() {
return this->hasMany('Project');
}
}
You also need to add $this to your Project relation:
class Project extends Eloquent
{
public function user()
{
return $this->belongsTo('User');
}
}