Join tables and fetch from Many to many (Laravel) - laravel

User Table
|---------------------|------------------|
| id | email |
|---------------------|------------------|
| 3 | 18 |
|---------------------|------------------|
Post Table
|---------------------|------------------|
| id | Title |
|---------------------|------------------|
| 12 | My Post |
|---------------------|------------------|
Category Table
|---------------------|------------------|
| id | Title |
|---------------------|------------------|
| 18 | My Category |
|---------------------|------------------|
Category-Post
|---------------------|------------------|
| post_id | category_id |
|---------------------|------------------|
| 12 | 18 |
|---------------------|------------------|
User-Category
|---------------------|------------------|
| user_id | category_id |
|---------------------|------------------|
| 3 | 18 |
|---------------------|------------------|
In this table structure, I want to fetch all the post with any given user id, according to their favorite category, with a single query.
I have defined the relations for all the models
Category:
public function posts(){
$this->belongsToMany(Post::class,'category-post','category_id','post_id')
}
Post:
public function categories(){
$this->belongsToMany(Category::class,'category-post','post_id','category_id')
}
User:
public function favCategories(){
$this->belongsToMany(Category::class,'user-category-','user_id','category_id')
}

Can try this with your relationship model
$data = User::with("favCategories.categories.posts")->find($user_id);
// "favCategories" get first of all favourite categories
// "categories" get all category
// "posts" get all post with these categories wise

Here is the single eloquent query:
<?php
dd($posts = User::find(3) //user id 3
->categories()->where('id', 18) //favorite category id 18
->posts);

Related

How to get data from nested relationship in Laravel 8 Eloquent?

How to make a deep relationship with eloquent? I'm trying to display the data like this :
+------------------------------------+
| Main ID | Name | SN | Last Event |
|------------------------------------|
| 12 | James | j89 | RIGHT |
+------------------------------------+
The "Last Event" column is based on the latest data on "Tracks" table but the value "RIGHT" is relation between the "Tracks" table with "Events" table. So, in this table, the latest record in the tracks table is id of 9 with event_id of 12, the event_id of 12 in the Events table has name column that contained value RIGHT. That value that I want to grab it to display in front end. this is my table in database.
Main table
+---------------+
|id | name | sn |
|---------------|
|12 | James| j89|
+---------------+
Tracks table
+-------------------------------------+
|id | main_id | event_id | created_at |
|-------------------------------------|
| 5 | 10 | 10 | 2021-10-12 |
| 9 | 10 | 12 | 2021-11-20 |
+-------------------------------------+
Events
+----------+
|id | name |
|----------|
|10 | LEFT |
|12 | RIGHT|
+----------+
If I use has one relationship with latestOfMany() method, it didn't reach to the events table. How do I reach it to the Events table to grab the value in Events table through the latest data of Tracks table based on main_id? thanks!
you can use Eager Loading to load deep in your relation, if you setup your relation correctly:
class Main extends Model
{
public function latestTrack()
{
return $this->hasOne(Track::class,'main_id')->latestOfMany();
}
}
class Track extends Model
{
public function event()
{
return $this->belongsTo(Event::class,'event_id');
}
}
now you can get the structre you need:
$main=Main::with('latestTrack.event:id,name')->find(12);

BelongsToMany by array values in laravel

How do I store data in users.sport_id:
User class:
public function sport() {
return $this->belongsToMany('App\Sport');
}
Where sports table has:
+----+------------+
| id | sport |
+----+------------+
| 1 | baseball |
+----+------------+
| 2 | basketball |
+----+------------+
Do I add to user.sport_id = 1,2 or save it as array [1,2] and use $casts = ['sport_id'=>'array'];

Laravel. How to get relationships where foreign key is an array

I am trying to retrieve database rows with their relationships. However, the local key is an array. Let me explain using an example.
Lets say I have a table of countries and a table of pages. Each country can have many pages. Each page can belong to multiple countries. I do not have the flexibility to change this schema.
pages
+-------------+-----------+
| id | name | countries |
+-------------+-----------+
| 1 | Page 1 | 1 |
+-------------+-----------+
| 2 | Page 2 | 1,2,3 |
+-------------+-----------+
| 3 | Page 3 | 4,5,6 |
+-------------+-----------+
countries
+----+----------------+
| id | name |
+----+----------------+
| 1 | United States |
+----+----------------+
| 2 | United Kingdom |
+----+----------------+
| 3 | Germany |
+----+----------------+
| 4 | France |
+----+----------------+
| 5 | Hong Kong |
+----+----------------+
| 6 | Thailand |
+----+----------------+
| 7 | Belgium |
+----+----------------+
| 8 | Singapore |
+----+----------------+
My model and controller look something like:
country
public function pages()
{
return $this->hasMany(Page::class, 'id', 'countries');
}
MemberController.php
$countries = Country::with('pages')->get();
This is returning all countries, but only Page 1 contains any relationships.
Is there a way to retrieve relationships using a whereIn approach so all three countries will return appropriate pages?
Thanks in advance
Since Page can belong to many Countries, you need to create a pivot table called country_page and remove the countries column.
Then define two belongsToMany() relationships in both models:
public function pages()
{
return $this->belongsToMany(Page::class);
}
If you're not following Laravel naming conventions listed in my repo and you gave the pivot name a custom name, define it too:
public function pages()
{
return $this->belongsToMany(Page::class, 'custom_pivot_table');
}
Something like this ?
$datas = Pages::where( ##your conditions### )->get()->inArray();
$countries = Countries::pluck('name','id'); // return array of id=>name
foreach($datas as $key=>$data) {
$c = [];
foreach(explode(',',$data['countries']) as $country_id) {
$c[]=$countries[$country_id];
//or
$c[]= ['id'=>$country_id,'name'=>$countries[$country_id]];
}
$datas[$key]['countries']= $c;
}

How to get record from post table in laravel using eloquen relationships

I have tow table first table is posts table and second table is home_posts table so i want to home_posts table (post_id) throw get record in posts table.
I was used hasMany() relationship in post model but not getting any record. I want only home_posts table post id record from posts table. I want home post table to post table record.
Post table
+----+-----------------+
| id | title |
+----+-----------------+
| 1 | Post 1 |
| 2 | Post 3 |
| 26 | Post 4 |
| 27 | Post 5 |
| 28 | Post 6 |
| 29 | Post 7 |
| 30 | Post 8 |
| 32 | Post 9 |
+----+-----------------+
home_post table
+----+------------+
| id | post_id |
+----+------------+
| 1 | 28 |
| 2 | 29 |
| 3 | 2 |
+----+------------+
In Post model:
public function home_posts()
{
return $this->hasMany('App\HomePost', 'post_id', 'id');
}
In HomePost model:
public function post()
{
return $this->belongsTo('App\Post', 'post_id', 'id');
}
To get post through home_post:
$homePost = \App\HomePost::find(1);
$post = $homePost->post;
or
$posts = \App\HomePost::has('post')->get();
To get home_post through post:
$post = \App\Post::find(1);
$homePost = $homePost->home_posts;
or
$homePost = \App\Post::has('home_posts')->get();
For more detail read this: One To Many
Hope it help you :)

Insert multiple values on multiple rows

I have a form that has a dropdown where the user can select up to 5 countries.
I have two related tables, users and countries, where each user can have multiple countries selected.
The users table:
+----+----------+----------------------+
| id | username | description |
+----+----------+----------------------+
| 1 | user1 | Some description. |
| 2 | user2 | Another description. |
+----+----------+----------------------+
The countries table:
+----+---------+---------------+
| id | user_id | country |
+----+---------+---------------+
| 1 | 1 | Canada |
| 2 | 1 | United States |
| 3 | 1 | France |
| 4 | 2 | Spain |
| 4 | 2 | Italy |
+----+---------+---------------+
As you can see, the country dropdown values should each have their own row in the table.
Here is my UserController so far (it only inserts into the users table for now):
$user = new User;
$user->username = Input::get('username');
$user->description = Input::get('description');
$user->save();
How would I insert multiple dropdown values such that each has its own row? What should my models look like for this to work?
If you're gonna use eloquent to do it, here's a suggestion:
//in your User model
public function countries()
{
return $this->hasMany('Country');
}
//insert from the controller
$countries = json_decode(Input::get('countries'), true); //assuming you use json to submit the multiple countries
$user_countries = array();
foreach($countries as $country)
{
$user_countries[]=new Country(array('country'=>$country));
}
//save the countries into the DB
$user->countries()->saveMany($user_countries);
for more info, do refer to the documentation:
http://laravel.com/docs/4.2/eloquent#inserting-related-models

Resources