Using eloquent in laravel to join third table. Best way to accomplish? - laravel

I am trying to join all videos for a given track along with joining the make and model from the vehicles table. Each video contains only one Vehicle from the vehicles table. I am having difficulties using Eloquent syntax on how I can make this happen.
The Track model i built to grab all the videos is very straight forward and works well as written below:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Track extends Model
{
public function video()
{
return $this->hasMany('App\Video');
}
}
I've written by Vehicles model as below:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
function vehicle()
{
return $this->hasOne('App\Vehicle');
}
}
The three database models look like the following
tracks
id
name
city
state
url_key
videos
id
youtube_id
date
best_lap_time
vehicles_id
vehicles
id
make
model

The below answer assumes your video() relation works well (as you said). But looking at your database schema and models, you don't have a column named track_id in your videos table, so I'm not sure about that.
Your vehicle relationship should look like this (you defined the inverse):
function vehicle()
{
return $this->belongsTo('App\Vehicle', 'vehicles_id');
}
Then your query should look something like this:
$result = \App\Track::with('video.vehicle')->get()

Related

hasOneThrough relationship Laravel

A contract has a representative (which is a user).
Currently I get this relationship with an belongsTo directly like this in my Contract model:
class Contract extends Model
{
public function representative()
{
return $this->belongsTo(User::class);
}
I would like to be able to retrieve this relationship through the organization_user table and retrieve the "position" attribute.
I think I should use the hasOneThrough relationship but I can't get what I'm looking for.
class Contract extends Model
{
public function representative()
{
return $this->hasOneThrough(User::class, OrganizationUser::class);
}
Not sure if you're in a position to change your DB structure, but it seems to me that your table contracts and organization_user are duplicating each other, storing the same data.
Would it make sense to leave only one table organization_user as a pivot table with the position?
Then you wouldn't need to make the big loop over few relationship to get the needed data.

How do I use a Laravel dynamic relationship?

I am a newbe in Laravel. The docs show how to use relationships like this:
One To Many (Inverse) / Belongs To
Now that we can access all of a post's comments, let's define a relationship to allow a comment to access its parent post. To define the inverse of a hasMany relationship, define a relationship method on the child model which calls the belongsTo method:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
/**
* Get the post that owns the comment.
*/
public function post()
{
return $this->belongsTo(Post::class);
}
}
Once the relationship has been defined, we can retrieve a comment's parent post by accessing the post "dynamic relationship property":
use App\Models\Comment;
$comment = Comment::find(1);
return $comment->post->title;
My question is: Where is this code? In a controller or in a view?
If you use MVC structure, you should understand that
Model is layer where you store your data
View is layer where you should only display your data
and Controller is layer where you can keep your logic.
If you have a lot of difficult logic or big application, you should better to use Services, as layer between Controllers And Models.
Receiving Comments from model and prepeare them should be in controller level. In view level you just define how to show them to user.
I hope it will help you to understand difference between logic layers.
you can access this relationship in controller or view like this-
suppose you want to make relation between product model and brand model:-
in product model:-
public function brand(){
return $this->belongsTo('App\Model\Brand','brand_id','id');
}
now you are able to see which product belongs to which brand without any query or using loop.
just do in controller:-
$product=Product::with('brand')->get();
here you get all the data...
and when you use it on **view **just do it:
{{$product->brand->brand_name}}
//brand name should the column name
I hope you understood...
Happy Learning!

Correct relationship in Laravel

I have four tables in database: groups, specialties, lessons, group_lesson. It's structures:
groups
id
specialty_id
name
specialties
id
name
lessons
id
specialty_id
group_lesson (UNIQUE INDEX lesson_id, group_id)
lesson_id
group_id
date
My models look like that for now:
class Group extends Eloquent {
public function specialty() {
return $this->belongsTo('Specialty');
}
}
class Lesson extends Eloquent {
public function specialty() {
return $this->belongsTo('Specialty');
}
}
class Specialty extends Eloquent {
public function lessons() {
return $this->hasMany('Lesson');
}
public function groups() {
return $this->hasMany('Group');
}
}
I need get additional fields in Group model look like that
Group - Eloquent model
name - string
lessons - collection of Lesson models of Group Specialty
date - date from group_lesson table
I've tried different relationships and combinations, but it's doesn't work. Please help me to write correct relationships.
You can use eager-loading to access relational data through relationships, and can even chain relationships further. As a rule of thumb, if you can draw a path to from 1 model to another through a relationship, you can eagerload all the relevant and relational data for that with chained eager-loads.
Laravel Eager Loading
As an example
$speciality_group = Speciality::with('group','lessons')->find($id);
Even though you are only getting a single instance of the speciality model, the related data is hasMany, meaning multiple records. You need to loop through these records using a foreach loop to access the relevant data for them, or alternitavely add additional closures in your initial query to load only a single related model.
foreach($speciality_group->group as $group)
{
echo $group->name;
}
You will need to do this for both instances where you want to display related information.

Laravel 4 Use the same Model and Controller for 12 lists for selects

I have to meke models, controllers and views for 12 tables. They have all the same structure id, name, order.
I was thinking and maybe using:
Controller
index($model)
$model::all()
return View::make(all_tables,compact('model'))
edit($model,$id)... and so on.
But and don't know if there's a way for using only one model.
Did anybody do anything like this?
Any idea?
Thanks
Although each model has the same table structure, what you're trying to achieve would not be advisable as you'd lose a lot of the fluent capabilities of Laravel's Eloquent ORM.
Regarding the controller, this would work:
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class GenericModelController extends Controller
{
public function loadModelById($model, $id)
{
$instance = \App::make('App\\' . ucfirst($model));
return $instance->find($id);
}
}
You'll need the following route:
Route::get('show/{model}/{id}', 'GenericModelController#loadModelById');
Example, to load a user with an id of 1:
http://www.yourdomain.com/show/user/1
Edit: I just saw that you're using Laravel 4, so the syntax for defining a route will be a little different I believe but the general concept will still work. Testing in Laravel 5 and works perfectly.
You should get get some idea from here.Please use the link below.
https://scotch.io/tutorials/a-guide-to-using-eloquent-orm-in-laravel
// app/models/Bear.php
class Bear extends Eloquent {
// MASS ASSIGNMENT -------------------------------------------------------
// define which attributes are mass assignable (for security)
// we only want these 3 attributes able to be filled
protected $fillable = array('name', 'type', 'danger_level');
// DEFINE RELATIONSHIPS --------------------------------------------------
// each bear HAS one fish to eat
public function fish() {
return $this->hasOne('Fish'); // this matches the Eloquent model
}
// each bear climbs many trees
public function trees() {
return $this->hasMany('Tree');
}
// each bear BELONGS to many picnic
// define our pivot table also
public function picnics() {
return $this->belongsToMany('Picnic', 'bears_picnics', 'bear_id', 'picnic_id');
}
}
I find a simple way.
Only one model, one controller and one view(index,edit, etc) too.
A single table with
id, name of list, value (name to appears in the list)
Yo pass can pass to de view all the values per list, and for any list in the table you can create de select if it's no empty.

Laravel 4: Keeping a table Relationship when reducing structure into several tables

History:
DB: Tables clients and titles
A Client can have many titles but a title can only have one client. So i will use a simple one-to-many relationship as illustrated below:
Client Model
class Client extends Eloquent {
public function titles(){
return $this->hasMany('titles');
}
}
Then i simply use the following to get the requested data for the selected title
$clientTitles = Client::find(1)->titles;
All in all this should list all client associated titles.
My question really comes to this as i am looking to split my data within my titles table into smaller tables as i also use some aspects of the titles data somewhere within the system and do not need to get all of the title details every time.
So i would have another three tables related to the titles data table
Titles, Title_Artwork, Title_Details, Titles_List
Now if i use the same as above i will get all the data within the titles table, but not the other three. So how can i then update my relationship to then scrape the other three title tables so when i need to, i can get all the data, rather.
Or is there another way to do this or NO keep to what i have done an just limit the call to the fields i require?
From what I understood, And lets assume that your Titles model is some what like-
class Titles extends Eloquent{
public function titleartwork(){
return ..
}
public function titledetails(){
return ..
}
public function titlelist(){
return ..
}
}
And your client model is-
class Client extends Eloquent {
public function titles(){
return $this->hasMany('titles');
}
}
So in order to get the data of any of these tables Title_Artwork, Title_Details, Titles_List
you can do this
$clientTitles = Client::with('Titles','Titles.titleartwork','Titles.titlelist')->where('id','=',1)->get();
In terms of Laravel it is known as Eager Loading, to know more you can check the doc
It will also work with multiple nesting, I mean if your Title_Artwork also contains relationship like-
class TitleArtwork extends Eloquent{
public function sometable(){
return ..;
}
}
Then you can get the data of sometable using
$clientTitles = Client::with('Titles','Titles.titleartwork.sometable','Titles.titlelist')->where('id','=',1)->get();

Resources