Laravel model relationship method - laravel

I have 3 tables
User (id,name,mail,mobile)
Contest (id,contest_name,contest_description)
Contest_user (id,user_id,contest_id)
I want to write a has many contest user method in the contest model also I need the user details from the method.
Kindly tell me how can I get the desired result.
Model Screenshot
<?php
namespace App\Model\Contest;
use App\Model\Project\ContestUsers;
use Illuminate\Database\Eloquent\Model;
class Contest extends Model
{
protected $table = 'contest';
protected $fillable = ['name','description'];
public $dates = [
'created_at',
'updated_at',
'deleted_at',
];
//I want to get user details from this method
public function project_contest_users()
{
return $this->hasMany(ContestUsers::class, 'contest_id', 'id')->whereNull('deleted_at');
}
}

contest_user is a pivot table for users and contests and should not have a model class.
The nature of the relation between User and Contest is a many to many, so you need to use belongsToMany() relation in both sides
Contest.php
public function users()
{
return $this->belongsToMany(User::class);
}
User.php
public function contests()
{
return $this->belongsToMany(Contest::class);
}

From what you have done, based on my experience, it's already a good thing that you normalize the many to many relationship. But what N69S said is also correct, that pivot table should not have a Model class, so you need to make your own convention to not use the Model class to create/update/delete (read is fine by me) and if you still want to stick to this method, what you need to do now is just defining the relationships for each of the Models.
User.php:
public function contest_user()
{
return $this->hasMany(ContestUser::class);
}
ContestUser.php:
public function user()
{
return $this->belongsTo(User::class);
}
public function contest()
{
return $this->belongsTo(Contest::class);
}
Contest.php:
public function contest_user()
{
return $this->hasMany(ContestUser::class);
}

Related

Laravel how to define 3 relationships with one model?

I have a Model which is called Championship. Championship may have 3 judges which are called Main Judge, Main Secretary and Judge Operator.
All of them linked to User Model and stored in the database as user ID.
My relationships looks like this
class Championship extends Model
{
protected $table = 'championships';
public function mainJudge()
{
return $this->hasOne('App\User', 'id', 'main_judge');
}
public function mainSecretary()
{
return $this->hasOne('App\User', 'id', 'main_secretary');
}
public function judgeOperator()
{
return $this->hasOne('App\User', 'id','judge_operator');
}
}
But I can't undertand how to define inverse relationship in User model
class User extends Authenticatable
{
public function sex()
{
return $this->belongsTo('App\Models\Sex');
}
public function player()
{
return $this->hasOne('App\Models\Player', 'user_id');
}
public function championship()
{
????
}
You just have to add it like you are adding other relations :
public function championship()
{
return $this->belongsTo('App\Championship');
}
When you do :
$championship = Championship::find($id);
$mainJudge = $championship->mainJudge;
$mainSecretary = $championship->mainSecretary;
// All objects will be exactly same
dd($mainJudge->championship,$mainSecretary->championship,$championship);
I assume all the user records have a foreign key to championships table championship_id
When you call the $user->championship relation it will return you the championship wrt to its foreign key championship_id
No need to worry you are just confusing the inverse relations:
See it this way:
Your mainJudge, mainSecretary, judgeOperators are of type App\User and every user have a championship_id when you will call the (App\User)->championship it will always return you its respective championship or null if the championship_id is empty.
Its just matter of perspective.
Just try the above code it will clear out your confusion.

Laravel 5.0 Selective Append or MorphThrough Relation

I know the subject is a little bit confusing. Let me explain.
For a medical software that I am currently developing, I have a data structure as below:
Patients has Protocols. Protocols has Examinations, Prescriptions or Reports, all polymorphic.
In some cases, I have to directly access to the Examinations of Patients. However, since this includes a polymorphic relation between Examination and Protocol, I cannot directly setup a relation method in my Patient model.
As a work around, I can set a custom getExaminationsAttribute and append this with $appends in Patient model. But this causes a whole load of data fetching when I try to get ,for example, only the name of a Patient.
Any help is appreciated.
Patient model:
class Patient extends Model{
protected $table = 'patients';
public function protocols(){
return $this->hasMany('App\Protocol', 'patients_id', 'id');
}
protected $appends = ['examinations'];
public function getExaminationsAttribute()
{
$examinations = array();
$this->protocols->each(function($protocol) use (&$examinations){
$protocol->examinations->each(function($examination) use (&$examinations){
$examinations[] = $examination->toArray();
});
});
return $examinations;
}
Protocol model:
class Protocol extends Model{
protected $table = 'protocols';
public function patient(){
return $this->belongsTo('App\Patient', 'patients_id', 'id');
}
public function examinations()
{
return $this->morphedByMany('App\Examination', 'protocolable');
}
Examination model:
class Examination extends Model{
protected $table = 'examinations';
public function protocols()
{
return $this->morphToMany('App\Protocol', 'protocolable');
}
As a workaround, patients_id column added to submodels of Protocol table (Examinations, Prescriptions etc.) and will be fetched via hasMany relationship.

Laravel 5 - Eloquent: easier way to filter a many to many relationship

I have a many to many relationship between Lists and Users.
This is the List Model:
class ListModel extends Model
{
protected $table = "lists";
public function users()
{
return $this->belongsToMany('App\Models\User', 'list_user', 'list_id', 'user_id')->withTimestamps();
}
}
This is the User model:
class User extends Authenticatable
{
public function lists()
{
return $this->hasMany('App\Models\ListModel');
}
}
In a list page, I need to get all the lists belonging to the logged user. The only solution I found is this one:
$user = \Auth::user()->id;
$all_lists = ListModel::whereHas('users', function ($query) use ($user) {
$query->where('user_id', $user);
})->active()->get();
is there any simpler way to achieve the same result?
Since current user is already loaded, you can use lazy eager loading to load lists for the user:
auth()->user()->load('lists');
Your lists() relationship is not defined correctly. The inverse of belongsToMany is still belongsToMany (hasMany's inverse is belongsTo):
class User extends Authenticatable
{
public function lists()
{
return $this->belongsToMany('App\Models\ListModel', 'list_user', 'user_id', 'list_id')->withTimestamps();
}
}
Then you can get the lists like this:
$user = \Auth::user();
$all_lists = $user->lists()->active()->get()

Laravel query multiple tables using eloquent

hi sorry bit of a newbie here but I am have three tables users, profiles, friends. they all have the user_id fields within them and I want fetch all of the fields in one statement using Eloquent and not DB::statement and doing the table joins.
How can I achieve this?
Try this
use the User class and the with method that laravel has to query model relationships
$user = User::with(['profile', 'friend'])->get();
Ensure your models has the correct relationships as follows:
app/models/User.php
public function friend () {
return $this->hasMany('Friend');
}
public function profile () {
return $this->hasOne('Profile');
}
app/models/Profile.php
public function user() {
return $this->belongsTo('User');
}
app/models/Friend.php
public function user() {
return $this->belongsTo('User');
}
use some thing like this:
You should define relations in your models with hasOne, hasMany.
class Review extends Eloquent {
public function relatedGallery()
{
$this->hasOne('Gallery', 'foreign_id', 'local_id');
}
}
class Gallery extends Eloquent {
public function relatedReviews()
{
$this->hasMany('Review', 'foreign_id', 'local_id');
}
}
$gallery = Gallery::with('relatedReviews')->find($id);
Will bring the object Gallery with
$gallery->id
gallery->name
...
$gallery->relatedReviews // array containing the related Review Objects

In Laravel, how to set up a relationship for a "likes" table? Also, how to include that information in a query?

I have three tables: users, ideas, and ideas_likes. The ideas_likes table looks like:
ideas_likes
------------
id primary key
user_id foreign key
idea_id foreign key
liked boolean
There's already a one-to-many relationship set up between users and ideas. It looks something like this:
class User extends Ardent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $table = 'users';
public function ideas()
{
return $this->hasMany('Idea');
}
}
Similarly, the idea model looks like this:
class Idea extends Ardent {
protected $table = 'ideas';
public function user()
{
return $this->belongsTo('User');
}
}
My first question is: How do I create the IdeaLike model? And once that is finished, using Eloquent, how do I retrieve all liked ideas for a user?
===========================================================================
Lucasgeiter's updated solution worked great.
First, there's no need to create an IdeaLike model. You just need a many-to-many relationship
User
public function ideas(){
return $this->belongsToMany('Idea', 'ideas_likes')->withPivot('liked');
}
Idea
public function users(){
return $this->belongsToMany('User', 'ideas_likes')->withPivot('liked');
}
(By adding withPivot I tell Laravel that I want to have the liked column from the pivot table included in the result)
Usage
$user = User::find(1);
$likedIdeas = $user->ideas()->where('liked', true)->get();
By the way: You don't need to specify the $table if it is the plural of the model name.
Update
It looks like you actually really do need both, a one-to-many and a many-to-many relation.
So your final relations would look like this:
User
public function ideas(){
return $this->hasMany('Idea');
}
public function liked(){
return $this->belongsToMany('Idea', 'ideas_likes')->withPivot('liked');
}
Idea
public function likes(){
return $this->belongsToMany('User', 'ideas_likes')->withPivot('liked');
}
public function user(){
return $this->belongsTo('User');
}
(I just chose names for the relations that made kind of sense to me. You can obviously change them)
Usage
Liked ideas by a certain user: (id = 1)
$ideas = Idea::where('user_id', 1)->whereHas('likes', function($q){
$q->where('liked', true);
})->get();

Resources