HasManyThrough with another relationship in Laravel 5.2 - php

I have 3 models:
Tournament, Category, Team
A Tournament hasMany Category
A Category hasMany Team
Tables:
Tournament: Only attributes
Category: id, tournament_id, name
Teams: id, category_id, name
I would like to get all teams from a tournament by: $tournament->teams
I tried :
public function teams()
{
return $this->hasManyThrough(Team::class,CategoryTournament::class);
}
Then I need an extra relation of my team: team->category->name;
but the result of this HasManyThrough has no relationship....
Any Idea???

In Category model :
public function team ()
{
return $this->hasMany('App\Teams');
}
In Teams model :
public function category ()
{
return $this->belongsTo('App\Category', 'category_id');
}

I think should be like this, Try.
According to laravel documentation :
countries
id - integer
name - string
users
id - integer
country_id - integer
name - string
posts
id - integer
user_id - integer
title - string
With this you can add relationship :
public function posts()
{
return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id');
}

Related

How to get all the people in table 1 without getting the people who have me as parent_id in table 2?

I'm writing this post because I have a problem with my relationships on Laravel.
Here is the structure I currently have:
1st table:
- id
- name
- ...
2nd table :
- parent_id
- child_id
knowing that parent_id and child_id correspond to the same table. Here is the function that links them
public function relation()
{
return $this->belongsToMany('App\Person', 'person_relations', 'parent_id', 'child_id', 'id', 'id');
}
Currently I would like, for a search system, to get all the people in table 1 without getting the people who have me as parent_id in table 2.
I have added an inverse relation parents() to the People model instead of the relation() method in the question.
Person Model :
public function parents()
{
return $this->belongsToMany('App\Models\Person', 'person_relations', 'child_id', 'parent_id', 'id', 'id');
}
Controller :
public function test()
{
$myId = 1;
$persons = \App\Models\Person::whereDoesntHave('parents')
->orWhereHas('parents', function($qry) use($myId){
$qry->where('person_relations.parent_id', '!=', $myId);
})
->get();
}
This method will return all records which doesn't have a given $myId as their parent id.
Tested and working in Laravel 6.2 and 7.29

Laravel relationship between three tables

I have 3 tables:
Events
Ages
Books
Which I was relating them in the following way:
ages
id
name
books
id
title
age_book
id
age_id
book_id
events
id
name
event_age
id
event_id
age_id
event_age_book
event_age_id
book_id
Basically, a book can have many ages, an age can have many books, an event can have many ages, an event age can have many books.
My Event Model looks like this and works fine to get all event ages
class Event extends Model
{
public function ages()
{
return $this->belongsToMany(Age::class, 'event_age');
}
}
Age Model:
class Age extends Model
{
public function books(): BelongsToMany
{
return $this
->belongsToMany(Book::class)
->withTimestamps();
}
}
Book Model
class Book extends Model
{
public function ages(): BelongsToMany
{
return $this
->belongsToMany(Age::class, 'book_age', 'book_id','age_id')
->withTimestamps();
}
}
Im having trouble figuring out how to get all edition age books, is it possible to do it on the Event model?
Let's Review The Relationships
Seems you should only need 3 models, and 5 tables.
Books Belong to Ages
Events Belong to Ages
Ages Belongs to Books
Ages Belongs to Events
Your other models are alright, but your age model is missing a relationship to Event:
class Age extends Model
{
public function books(): BelongsToMany
{
return $this->belongsToMany(Book::class)
->withTimestamps();
}
public function events(): BelongsToMany
{
return $this->belongsToMany(Events::class,'event_age')
->withTimestamps();
}
}
That would allow:
$books->ages;
$events->ages;
$ages->book;
$ages->events;
And chaining...
$books = collect();
foreach($event->ages as $age){
$books->merge($ages->books);
}
$books->unique();
Books and Events
So, I gon't think you want age_event_books. I think what you really want is:
Events belong to Books
Books belong to Events
such that
book_events
- id
- book_id
- event_id
- age_id
And you'd have in book:
public function events()
{
return $this->BelongsToMany('App\Event')
->withTimestamps()
->withPivot('age_id');
}
And in event:
public function books()
{
return $this->belongsToMany('App\Book')->withTimestamps()
->withPiviot('age_id')->groupBy('age_id');
}
Giving you:
$event->books
$book->events
On the Front End
[O]n the frontend i'll need to get the most recent event and group books by age and books can belong to more than one age
$event = Event::latest();
$books = $event->books();
Then on the blade
#foreach($books as $age_id => $books)
<h4>{{Age::find($age_id)->name}}</h4>
#foreach($books as $book)
<div>$book->name</div>
#endforeach
#endforeach
Helpful Tip
You are supplying the relation table, which you have to do because you didn't follow the naming convention for joining tables. The convention is that the classes being joined should be listed alphabetically. So age_event instead of event_age.

How to relate one model to 2 different models?

I have the following tables:
user_details
id - PK
user_name
user_email
cities
id - PK
city_name
regions
id - PK
region_name
city_id - FK(cities)
user_region (Many to Many)
user_id
region_id
And these are the models:
User
public function regions()
{
return $this->belongsToMany('App\Regions', 'user_region', 'user_id', 'region_id');
}
Regions
public function cities()
{
return $this->belongsTo('App\Cities');
}
public function users()
{
return $this->belongsToMany('App\User', 'user_region', 'region_id', 'user_id');
}
Cities
public function regions()
{
return $this->hasMany('App\Regions', 'city_id', 'id');
}
I need to get the city name for a user. Which relation can I use here to do this?
According to your comment:
A city can have many regions. And a user can work in many regions. But, the user will only work in a single city.
As all regions which user belongs to will belong to only one city you can do as follow:
$user = User::find(1);
$city = $user->regions()->first()->cities;
echo $city->city_name;

Relationship between a hasMany and belongsToMany in Laravel

I have two Models - InternalNotesThread and InternalNotes
class InternalNotesThread extends Model {
public function notes(){
return $this->hasMany('App\InternalNotes', 'thread_id', 'id');
}
}
class InternalNotes extends Model {
public function thread() {
return $this->belongsTo('App\InternalNotesThread');
}
public function users()
{
return $this->belongsToMany('App\User', 'user_notes_tagged', 'internal_notes_id', 'user_id');
}
}
Also, InternalNotes is mapped to User with a relation of belongsToMany.
DB Structure:
internal_notes_thread:
id - int
ticket_id (FK) - int
name - string
internal_notes:
id - int
thread_id (FK) - int
notes - string
user_notes_tagged: (Many to many with internal_notes and User)
internal_notes_id (FK) - int
user_id (FK) - int
For every note, there might be some user tagged in it.
How can I directly relate this relationship with the internal_notes_thread???
I get the data with this:
$data = InternalNotesThread::with('notes')->where('ticket_id', '=', $id)->get()->toArray();
But, in the notes array, I am not able to get the users tagged in that note
How can I get all the data in one go???
You're not eager loading the users, so they don't show up in your ->toArray() array.
Try this:
$data = InternalNotesThread::with('notes.users')
->where('ticket_id', '=', $id)
->get()
->toArray();

Laravel 4 Relations belongsTo on multiple tables

I'm trying to do a stystem of comments and posts with laravel 4 where 2 type of "user" can comments. For 2 type of "user" means that i have a table User and a table Teams and my expectations are that both can let comment on the posts of the opposite. Let'go with the logic that i used untill now:
Schema tables:
User Table
Table | Users
id - integer autoincrement
fullname - string 20
Team table
Table | Teams
id - integer autoincrement
fullname - string 50
Posts table
Table | Posts
id - integer autoincrement
text - text
id_poster - integer
type_id - integer // if is 1 the id_poster filed belongs to user else if 2 belongs to team
Comments Table
Table | Comments
id - integer autoincrement
id_post - integer
id_poster - integer
id_type - integer
text - text
And now let's go with the relations:
Users relation
Class User extends Eloquent {
protected $table = "users";
function posts() {
return $this->hasMany('Post','id_poster');
}
function comments() {
return $this->hasMany('Comment','id_poster');
}
}
Team relation
Class Team extends Eloquent {
protected = $table = "teams";
function posts() {
return $this->hasMany('Post','id_poster');
}
function comments() {
return $this->hasMany('Comment','id_poster');
}
}
Posts relation
Class Post extends Eloquent {
protected $table = "posts";
function users() {
$this->belongsTo('User','id_poster');
}
function teams() {
return $this->belongsTo('Team','id_poster');
}
function comments() {
return $this->hasMany('Comment','id_post');
}
}
Comments relation
Class Comment extends Eloquent {
protected $table = "comments";
function posts() {
return $this->belongsTo('Post','id_post');
}
function teams() {
return $this->belongsTo('Team','id_poster');
}
}
with this kind of relations i can get posts and comments about just an individual category:
example i do the results for the users posts and comments
$posts = new Post;
$get_post = $posts->with('users','comments.users')->where('type_id','=',1)->get();
i can display
users posts and users comments OR
teams posts and teams comments
but not
Users posts and teams / users comments
Team posts and users / teams comment
The datas need it for my output about the comments are:
- id_poster
- fullname
- id_type
- text
In few words my question is:
What i have to change and why for do appear the comments of both the "user"?

Categories