With this code :
$evenements = Year::with(['evenements' => function($query) {
return $query->orderBy('mnemonique');
}])
->orderBy('id')
->get();
I get that:
5 => array:7 [▼
"id" => 62
"name" => "Congé"
"mnemonique" => "Congé"
"color" => "#bcbcbc"
"created_at" => "2021-07-13T14:16:04.000000Z"
"updated_at" => null
"pivot" => array:2 [▼
"year_id" => 1
"evenement_id" => 62
The problem is that pivot should have 10 items and not only 2 because the event 62 is in 5 years
This is the models code:
Events model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Evenement extends Model
{
protected $fillable = ['name','mnemonique','color'];
//DD 18/07/21 Une année peut avoir plusieurs events
public function years()
{
return $this->belongsToMany(Year::class, 'evenement_year', 'evenement_id', 'year_id');
}
}
Year model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Year extends Model
{
protected $fillable = ['name'];
public function evenements()
{
return $this->belongsToMany(Evenement::class, 'evenement_year', 'year_id', 'evenement_id');
}
}
This is the content of $query :
Illuminate\Database\Eloquent\Relations\BelongsToMany {#260 ▼
#table: "evenement_year"
#foreignPivotKey: "year_id"
#relatedPivotKey: "evenement_id"
#parentKey: "id"
#relatedKey: "id"
#relationName: "evenements"
#pivotColumns: []
#pivotWheres: []
#pivotWhereIns: []
#pivotWhereNulls: []
#pivotValues: []
+withTimestamps: false
#pivotCreatedAt: null
#pivotUpdatedAt: null
#using: null
#accessor: "pivot"
#query: Illuminate\Database\Eloquent\Builder {#1478 ▶}
#parent: App\Year {#1474 ▶}
#related: App\Evenement {#1475 ▶}
}
I don't know how to feed pivot array ? Do you have any idea ?
Thank you in advance.
You must specify extra columns in your relationship using withPivot; since I do not know your column names (cropped in image), I will just give an example:
class Year extends Model
{
protected $fillable = ['name'];
public function evenements()
{
return $this->belongsToMany(Evenement::class, 'evenement_year', 'year_id', 'evenement_id')
->withPivot(["someField1", "someFiled2"]);
}
}
Related
I need to create a single objective that has a multi-select drop down wherein different departments can share that same objective. I wanted to create a relationship table with an output like this.
Department Table
id | name
1 Science Department
2 Math Department
3 Biology Department
Objective Table
id | name
1 Be the best
Relationship Table
objective_id | department_id
1 1
1 2
1 3
This is what I think of inside the controller.
public function store(Request $request) {
$objective = Objective::updateOrCreate(
[ 'id' => $request->id ?? null ],
[ 'name' => $request->name ]
);
// From multiple select drop down
foreach($request->departments as $department) {
RelationshipTable::updateOrCreate(
[ // what should be the case? ],
[
'objective_id' => $objective->id,
'department_id' => $department['id'],
]
);
}
}
I'm not sure on how I would define this in the Model and how I could call their relationship inside the resource. I even think that my controller is wrong or are there better ways to achieve this?
First You are running query under loop is a very bad process.. may this process will help u? change it as your need!
public function store(Request $request) {
$objective = Objective::updateOrCreate(
[
'id' => $request->id ?? null,
'name' => $request->name
]
);
// From multiple select drop down
$insert_array = [];
foreach($request->departments as $department) {
array_push($insert_array,[
'objective_id' => $objective->id,
'department_id' => $department['id'],
]);
}
RelationshipTable::updateOrCreate($insert_array);
}
//Relationship Should Be Like in this example
Relationship Model
public function object() {
return $this->hasOne('Model Class of Object' , 'objective_id ' , 'id')
}
public function depertment() {
return $this->hasMany('Model Class of depertment' , 'department_id' , 'id')
}
Lets say this is my table structure:
posts
id - integer
title - string
body - text
reviewed - boolean
videos
id - integer
title - string
url - string
profileContent
id - integer
user_id - integer
content_id - integer
content_type - string
Now I want to receive the contents of the user's profile:
$user->profileContents()
->latest()
->with(['content' => function ($query){
//I'm not sure how to do it
}])
->paginate(5);
How do I say that IF the column "reviewed" exists it should be true? But it does not matter if videos are reviewed or not.
Additional Informations:
profileContents() gives me all the contents of a user profile
public function profileContents()
{
return $this->hasManyThrough(ProfileContent::class, Profile::class);
}
and with('content') uses to morph to the specific models:
public function content()
{
return $this->morphTo();
}
Edit 1:
I'm a bit nearer to my goal. I used a GlobalScope to only show content that is reviewed.
In Post:
protected static function boot()
{
parent::boot();
static::addGlobalScope('reviewed', function (Builder $builder) {
$builder->where('reviewed', true);
});
}
But now I have the problem that I still cannot exclude an empty query. I show you the output:
//ProfileContent
array:2 [
0 => array:8 [
"id" => 1
"profile_id" => "1"
"content_id" => "1"
"content_type" => "App\Video"
"content" => "[some array values]"
]
1 => array:8 [
"id" => 2
"profile_id" => "1"
"content_id" => "1"
"content_type" => "App\Post"
"content" => null
]
]
How can I exclude the null array without losing the paginated data (output should be 5)
Review your question one more time u are accessing relationship and then trying to eagerload the relationship again. I am pretty sure this is what you want:
$user->contents()
->latest()
->with(['posts' => function ($query){
//here you add a query constrain on eagerload like:
$query->where('reviewed', true);
}])
->paginate(5);
I'm trying to get if user following or no the page. I'm try like this:
class Page extends Model
{
public function get_following()
{
return $this->belongsTo(Followers::class, 'user_id')->where('type', '=', 1)->where('follower_id', auth()->user()->id)->Select('id');
}
}
But this return null.
dd($page)
Page {#303 ▼
#attributes: array:9 [▼
"id" => 1
]
#relations: array:3 [▼
"ptag" => Tag {#307 ▶}
"get_following" => null
Table followers:
followers.user_id = (pages.id), follower_id = (auth user), type = (1)
Thank you.
change select to ->value('id')
public function get_following()
{
return $this->belongsTo(Followers::class, 'user_id')->where('type', '=', 1)->where('follower_id', auth()->user()->id)->value('id');
}
Try:
public function get_following()
{
return $this->belongsTo(Followers::class, 'user_id')
->where('type', '=', 1)
->where('follower_id', auth()->id())
->pluck('id');
}
public function get_following()
{
return $this->belongsTo('\App\Followers', 'user_id')
->where('type', 1)
->where('follower_id', Auth::user()->id())
->pluck('id');
}
I have models: Partido and Coalicion related in a many to many relationship.
I need to know when two or more Coalicion has the same Partido related.
Hope I have explained myself.
Edit 1:
Model:
class Coalicion extends Model
{
public function partidos()
{
return $this->belongsToMany(Partido::class);
}
}
Let's say users selected some elements from a select input and I grabbed them in an array and send them to the controller.
...
public function example(Request $request)
{
$coaliciones = $request->coaliciones;
foreach ($coaliciones as $c) {
$coalicion = Coalicion::find($c);
# Here we have a list of Coalicion model in a loop
# Let's say the first iteration I can see the relationship
dump($c->partidos);
}
}
This for example give me the following answer at the browser:
Collection {#1 ▼
#items: array:2 [▼
0 => Partido {#271 ▶} #This is Partido with id 1
1 => Partido {#268 ▶}
]
}
Collection {#2 ▼
#items: array:3 [▼
0 => Partido {#279 ▶}
1 => Partido {#280 ▶}
2 => Partido {#283 ▶} #This is Partido with id 1
]
}
I need to know when the item 0 of the first Collection and the item 2 of the second Collection are the same.
I kinda found a way but I don't know if it's the correct or best approach.
In Coalicion model I add the following function:
public function partidosId()
{
return $this->partidos->pluck('id');
}
With this I can get only the id's from the relations, then in the controller I created an empty array() and fill it with all my ids with a foreach loop, then, finishing up I evaluated if the id's in the now filled array are unique, if the unique values are less than the length of the array then some models have the same relation (I don't know which but It's a start), e.g.:
public function example(Request $request)
{
$coaliciones = $request->coaliciones;
$allItems = [];
foreach ($coaliciones as $c) {
$coalicion = Coalicion::find($c);
$allItems = array_merge($allItems, $coalicion->partidosId()->toArray());
}
if (count(array_unique($allItems))<count($allItems)) {
dd("Duplicates");
}else{
dd("Uniques");
}
}
If anyone find a better way or a way to know which are the ones with the duplicate relation please let me know
I have an Artist model and an Item model.
class Artist extends Model {
protected $table = 'contactsdata';
protected $primaryKey = 'c_id';
public function artworks() {
return $this->hasMany('App\Item', 'c_id', 'c_id');
}
}
class Item extends Model {
protected $table = 'stock';
protected $primaryKey = 's_id';
}
In my ArtistsController I have this code:
public function show($id)
{
DB::enableQueryLog();
$artist = Artist::find($id);
$artworks = Artist::find($id)->artworks;
dd(DB::getQueryLog(), $artworks->toArray());
}
In the database there are many records qualifying to populate $artworks. But this is my dd() output:
array:2 [▼
0 => array:3 [▼
"query" => "select * from `contactsdata` where `contactsdata`.`c_id` = ? limit 1"
"bindings" => array:1 [▼
0 => "2242"
]
"time" => 2.59
]
1 => array:3 [▼
"query" => "select * from `stock` where `stock`.`c_id` is null"
"bindings" => []
"time" => 2.52
]
]
[]
For some reason the if field (c_id) is set to null for the second or relationship query. Any ideas? Help!
To achieve what you want, you should rather use here:
$artist = Artist::find($id);
$artworks = $artist->artworks;
instead of:
$artist = Artist::find($id);
$artworks = Artist::find($id)->artworks;
Thanks all. I have solved this myself. Eloquent relationship field names are case sensitive. For some reason my database table has all its fields (in its scheme) named in UPPER CASE. Once I changed the hasMany parameters to 'C_ID', 'C_ID' everything worked just fine.
So worth knowing that Eloquent relationship field names are CASE SENSITIVE.