hasManyThrough() or similar database model - laravel

I have a database setup similar to this:
items
id - integer
user_id - int
users
id - integer
name - string
contacts
id - integer
user_id - integer
name - string
Using Eloquent ORM how would I query for that returns the associated user, and their contacts? I'm currently using
Items::with('user')->get();

Models and relationship:
// User model
class User extends Eloquent {
public function items()
{
return $this->hasMany('Item');
}
public function contacts()
{
return $this->hasMany('Contact');
}
}
// Contact model
class Contact extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
// Item model
class Item extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
Usage:
$items = Item::with('user.contacts')->get(); // Result will be a collection object
$firstItem = $items->first(); // get the first item from collection
// Or this to get first one
$firstItem = $items->get(0); // get the first item from collection
$firstItem->user; // Get related User Model
$firstItem->user->contacts; // get collection of Contact models
If you pass the $items to your view then you may use a loop, for example:
$items = Item::with('user.contacts')->get();
return View::make('viewname')->with('items', $items);
In your view:
#foreach($items as $item)
{{ $item->property_name }}
{{ $item->user->property_name }}
#foreach($item->user->contacts as $contact)
{{ $contact->propertyname }}
#endforeach
#endforeach

It's called loading nested relations - last example on http://laravel.com/docs/eloquent#eager-loading
$items = Items::with('user.contacts')->get();
// then for example:
$item = $items->first();
$item->user; // user Model
$item->user->contacts; // Collection of Contact models
A note: there is no relation to access such relation directly. hasManyThrough won't work in this setup.

Related

Laravel query builder with the User and Auth

How to List all rows from a table (agendas) in my DB where records are saved by the connected user.I'm using default Auth from Laravel.
public function index ($id = null)
{
$agendas = Agenda::where('id', Auth::user()->id)->get();
$users = User::all();
return view('admin.agendas.index', compact('agendas','users','id'));
}
My controller here.
Need help
Assuming
agendas table (containing records for Agenda model) has a column user_id which references the id column on users table
User hasMany Agenda
Agenda belongTo User
class User extends Model
{
public function agendas()
{
return $this->hasMany(Agenda::class);
}
//... rest of class code
}
class Agenda extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
//... rest of class code
}
public function index($id = null)
{
$user = User::with('agendas')->findOrFail(auth()->id());
return view('admin.agendas.index', [
'user' => $user,
'agendas' => $user->agendas,
'id' => $id
]);
}
Your User model should have a relationship:
public function agendas()
{
return $this->hasMany(Agenda::class);
}
In your controller, you could then simplify the use as such:
public function index (Request $request, $id = null)
{
$agendas = $request->user()->agendas;
$users = User::all();
return view('admin.agendas.index', compact('agendas','users','id'));
}
if you wanna get data related to another data , you have to join those tables together by a field. in this case i guess you have a column in Agenda table named 'user_id'.
you have two way :
join tables in your Model.
search in Agenda table in your controller
if you want to use joining your tables from model :
// in App\User.php
...
class User ...{
...
public function Agenda(){
return $this->hasMany(Agenda::class);
}
...
}
...
then you can access to all of "Agenda" from everywhere like this :
Auth()->user()->agenda
if you want to search in table from your controller you can do :
Agenda::where('id', Auth::user()->id)
you can read more about eloquent-relationships in : https://laravel.com/docs/8.x/eloquent-relationships

laravel model controller retrieve data

I'am new to laravel and had a hard time for eloquent ORM, I like to retrieve Favourite items from the table with specific user id, but seem I don't find a way to display the data correctly.
I refer and copied the favourite model code from here
Model: Favourite
class Favourite extends BaseModel
{
public function favouritable()
{
return $this->morphTo();
}
}
Model: Course
public function favourites()
{
return $this->morphMany(Favourite::class, 'favouritable');
}
public function myFavourite()
{
return $this->favourites()->where('favor_user', '=', auth()->user()->id);
}
Controller: FavouriteController#index
public function index()
{
$course = new Course();
$myfavs = $course->myFavourite();
//dd($myfavs);
$this->vdata(compact('myfavs'));
return view('front.favorites', $this->vdata);
}
In blade view, but return empty/blank data:
#foreach($myfavs as $myfav)
{{ $myfav->$course_name }}
#endforeach
When i dd($myfavs) it display pretty bunches of data that i couldn't find the data that is stored in the favourites table.
I think you have added the conditions but forgot get the results with one of the methods to do so.
Try :
$myfavs = $course->myFavourite()->get();
Or :
$myfavs = $course->myFavourite()->take(<N>)->get;
Or
::all()
etc. take a look at : https://laravel.com/docs/5.8/eloquent#retrieving-models

Laravel One To Many Relationship

I have an Author model and Blog model.
I also set up a table with the author_id and blog_id. The table is called "author_blog".
Below is how I am defining my relationships:
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog', 'author_id');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author', 'blog_id');
}
In my view I am trying to do $blog->author->first_name. The first name is a column on the Authors table.
I keep getting
trying to get property on non-object.
Any ideas?
UPDATE:
I have removed the intermediate table and instead put an "author_id" on my blogs table and shortened it as such.
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author');
}
In my BlogController, when I define the view, I grab a collection of blogs via $blogs = Blog::all();
In my view I just loop through the blogs to show each individually like...
#foreach ($blogs as $blog)
<div>{{ $blog->author->first_name }}</div>
#endforeach
For one to many relationship you don't need another table to handle your foreign key.
Just add author_id foreign key with your blogs table. then define your relations
like below,
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog', 'author_id');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author', 'author_id');
}
view:
before that make sure your query return a valid collection.
#foreach ($blogs as $blog)
<div>#if( $blog->author) {{ $blog->author->first_name }} #endif </div>
#endforeach
For further more details : https://laravel.com/docs/5.8/eloquent-relationships#one-to-many
with belongsToMany relation you can define your middle table(author_blog)
In Author model:
public function blogs()
{
return $this->belongsToMany(Blog::class,'author_blog','author_id','blog_id');
}
author_blog => middle table
author_id => foreignPivotKey
blog_id => relatedPivotKey

hasOne Relation not working in laravel

Hi I want to make relationship between two tables first Table is product and second is productimages
ProductController.php
public function product(){
$products = Product::all();
dd($products->images);
}
Product.php (modal)
class Product extends Model
{
public $timestamps = false;
//
public function images()
{
return $this->hasOne(ProductImage::class);
}
}
ProductImage.php(model)
class ProductImage extends Model
{
public function product(){
return $this->belongsTo(Product::class);
}
}
When i am using this method $products = Product::find(1); working find but i need all.
Thanks
When you're doing $products->images you're trying to access property of collection.
Preload all products with their images, use with() method:
$products = Product::with('images')->get();
Then you'll be able to get image of each product and avoid N + 1 problem:
#foreach ($products as $product)
// Access $product->image here
#endforeach
Product::with('images')->get();

laravel display only specific column from relation

I have read a few topics about this, but they managed to solve my problem partially ...
this is my controller
class DeskController extends BaseController{
public function getDeskUsers($deskId){
$user = DeskUserList::where(function($query) use ($deskId){
$query->where('deskId', $deskId);
})->with('userName')->get(array('deskId'));
if (!$user->isEmpty())
return $user;
return 'fail';
}
this is the model
class DeskUserList extends Eloquent {
protected $table = 'desk_user_lists';
public function userName(){
return $this->belongsTo('User', 'userId')->select(array('id','userName'));
}
}
the method getDeskUsers may returns ALL the DeskUserList table records, related with the User table record (on deskUserList.userId = User.id).
practically I want each record returned is composed of:
DeskUserList.deskId
User.userName
eg. [{"deskId":"1","user_name":antonio}]
What i get is
[{"deskId":"1","user_name":null}]
As you can see the user name is a null value...
BUT
if I edit my controller code:
->with('userName')->get(array('userId')); //using userId rather than deskId
then i get
[{"userId":"2","user_name":{"id":"2","userName":"antonio"}}]
By this way I still have two problem:
the userId field is twice repeated
I miss the deskId field (that I need...)
hope be clear, thanks for your time!
You need belongsToMany, no need for a model representing that pivot table.
I assume your models are Desk and User:
// Desk model
public function users()
{
return $this->belongsToMany('User', 'desk_user_list', 'deskId', 'userId');
}
// User model
public function desks()
{
return $this->belongsToMany('Desk', 'desk_user_list', 'userId', 'deskId');
}
Then:
$desks = Desk::with('users')->get(); // collection of desks with related users
foreach ($desks as $desk)
{
$desk->users; // collection of users for particular desk
}
// or for single desk with id 5
$desk = Desk::with('users')->find(5);
$desk->users; // collection of users
$desk->users->first(); // single User model

Resources