eloquent multi table query and relationships - laravel

I am new to this so bear with me.
I have 4 tables (users, scores, scorecards, courses) and I need to bring into a view info from all of these tables.
Here are the relationships:
Scores model
public function user(){
return $this->belongsTo('App\User');
}
public function scorecard(){
return $this->belongsTo('App\Scorecard');
}
public function course() {
return $this->belongsTo('App\Course');
}
Course model
public function club(){
return $this->belongsTo('App\Club');
}
public function scorecard(){
return $this->hasMany('App\Scorecard');
}
public function score() {
return $this->hasMany('App\Score');
}
Scorecard model
public function course(){
return $this->belongsTo('App\Course');
}
public function club(){
return $this->belongsTo('App\Club');
}
In my controller I get the scores id from a dropdown in the request. I need to essentially get the following info:
the scores record which is easy as i have the score id.
use the scorecard_id from the scores table to get the scorecard record from the scorecards table
grab the course info from the courses table using the course_id thats in the scorecards table.

You can eager load the relations using dot . as scorecard.course and it will load both scorecard and course.
$score = Score::with('scorecard.course')->find($id);
and then you can access corresponding attributes as:
$score->scorecard;
$score->scorecard->course;

if $id is the scores id from a dropdown,
$score=Score::with('scorecard','scorecard.course')->where(['id'=$id])->first();
then,
print_r($score);
gives the scores record.
print_r($score->scorecard);
gives the scorecard record.
print_r($score->scorecard->course);
gives the courses record.

Related

Laravel Eloquent Relationship by Models

I have a table called "categories" and there is a 3 table needed the id of categories
the 3 tables needed a categories id is "activies", "stories", "news" i really want to know how to fix this issue the stories and news table is running well im using php tinker to see if the relationship is running and the table activities it give me a null value, inside the activities table i`d input same category_id in the table of activities it gives always a null value given in php tinker
Models
Category.php
public function stories()
{
return $this->hasMany(Story::class);
}
public function news()
{
return $this->hasMany(Newy::class);
}
public function activites()
{
return $this->hasMany(Activity::class);
}
Activity.php
public function category()
{
return $this->belongsToMany(Category::class, 'category_id');
}
If you are using hasMany in your Category Model, the opposite relationship in your Activity model should be belongsTo() and not belongsToMany()
public function category()
{
return $this->belongsTo(Category::class);
}
You can read more in the documentation here

Using HasManyThrough in Laravel

I have the following structure:
orders
id
name
products
id
name
items
id
order_id
product_id
quantity
The relationships are as follows:
Order
public function items(){
return $this->hasMany(Item::class)
}
public function products(){
return $this->hasManyThrough(Product::class, Item::class);
}
Item
public function order(){
return $this->belongsTo(Order::class);
}
public function product(){
return $this->belongsTo(Product::class);
}
Product
public function items(){
return $this->hasMany(Item::class);
}
I wish to get all products for the order doing something like this:
$order->items()->products()->get() using the hasManyThrough method, but I must be doing it wrong since it tries to look for item_id in the products table.
I realized that I do not need many through, I just need to use items table as a pivot table, defining the relationship on the Order model just like this:
public function products(){
return $this->belongsToMany(Product::class, 'items');
}

Laravel Eloquent Relation Model

I have 3 table on my database :
table 1 = user (hasMany order)
table 2 = order (hasMany order_detail, belongsTo user)
table 3 = order_detail (belongsTo order)
On my order_detail model i add this function :
public function order() {
return $this->belongsTo('App\Order');
}
so i can call the order data without define it from controller, i just define order_detail on my controller
$order_detail->order->invoice_number
but how to call the user data from the order detail?
I try use this
$order_detail->order->user
but it didn't work for me..
Is there any idea to call the grand parent relation?
In order model add function for order_detail:
public function order_details() {
return $this->hasMany('order_detail');
}
and for user:
public function user() {
return $this->belongsTo('user');
}
In user model add:
public function orders() {
return $this->hasMany('order');
}
Then, you can call in the controller:
$details = Order::find(1)->order_details->where('order_detail_id', 5)->first();
$userName = $details->username;
// ^
// column name in order_detail table
More info in the docs.
I think this is the more complete way to define the relationships:
// User model
public function orders(){
// I'm telling that users has many order. The orders have an user_id field that match with the ID field of the user.
return $this->hasMany('App/Order', 'user_id' , 'id');
}
// Order model
public function order_details(){
// I'm telling that order has many order_details. The order_details have an order_id field that match with the ID field of the order.
return $this->hasMany('App/OrderDetail', 'order_id' , 'id');
}
public function user(){
// I'm telling that an order belongs to an user. The user has an ID field that match with the order_id field of the order.
return $this->belongTo('App/User', 'id', 'user_id');
}
// OrderDetail Model
public function order(){
// I'm telling that an order detail belongs to an order. The order has an ID field that match with the order_id field of the order detail.
return $this->belongTo('App/Order', 'id', 'order_id');
}
I have seen that you put just the model name as first parameter in your relation definition. I think you must put the relative path from the root to the Model. In my case, I have the models as childs of the App folder.

laravel 5 pivot table

I'm trying to implement a friendlist for a user
so a user can have many friends
but for calling the friends I'm having trouble getting my relation right:
user
id
friends
user_id
friend_user_id
Class user:
public function Friends(){
return $this->hasMany('App\User', 'friends');
}
So Auth::User()->Friends should return a list of User models
You actually don't have a "one to many" relationship but rather "many to many" with friends being your joining table
Try this:
public function Friends(){
return $this->belongsToMany('App\User', 'friends', 'user_id', 'friend_user_id');
}
When creating a relation to the same model, you would do something like this:
Models/User.cs
public function Friends()
{
return $this->hasMany('User', 'user_friend_of', 'id'); // assuming user_friend_of is the FK on user-table
}
public function User()
{
return $this->belongsTo('User');
}
This would mean you have only 1 table, which has a foreign key to another row in the same table, for instance: (id - name - user_friend_of )
In your user class, define the function as follows:
public function Friends(){
return $this->hasMany('friends');
}
Calling $user->Friends()->get() should return you everything you need. Note that 'friends' should be the name of the table.

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