Joining Two Tables to a Reference Table Laravel - mysql

I Have three tables
#1 Table timeline which is my reference table with an Auto incremented ID which is stored in column id
#2 timeline_videos
#3 timeline_else
What happens is on post if a video is uploaded with the post
it will go into Table #2 ,anything else goes into Table #3.
#2-3 have the Auto Increment Id from the Table timeline stored in a column pid
On query of The Timeline I need to join both tables data using id=pid
so I can use the rest of the Relational Data with the post.
I have done a bit of research and can't seem to find a method for doing so.
So far the code I have
Controller
$groupposts = timeline::where([
['owner','=',$owner],['id','<',$lastid],
])
->join('timeline_videos','timeline.id','=','timeline_videos.pid')
//->join('timeline_else','timeline.id','=','timeline_else.pid')
->orderBy('id','desc')
->limit(5)
->get();
This works with no errors with the second Join commented out but I need to also grab the timeline_else data .
Update --
I have now decided to use Eloquent Relationships to join the tables,
my question now is what type of relationship do I have between the
tables?
I realize it basically needs to be able to switch between two tables to
grab data based on the fact that timeline_videos and timeline_else will not be "JOIN" but separated by type .
The tables need to Join with table #1 timeline based on a column I now have named type for clarifying where to look and matching/joining using the id = pid

You can use relationships.
it sounds like timelines has many videos and has many video failures
https://laravel.com/docs/5.5/eloquent-relationships#one-to-many
you would have a model for each table and set up the relationships
timelines model:
public function videos()
{
return $this-> hasMany('App\Videos');
}
public function videoFailures()
{
return $this-> hasMany('App\videoFailures');
}
videos model:
public function timeline()
{
return $this->belongsTo('App\Timelines');
}
videos failures model:
public function timeline()
{
return $this->belongsTo('App\Timelines');
}
You can then go:
$timeLine = Timmeline::find($id);
to find videos of the time lines you would do:
$videos = $timeLine->videos();
to find else:
$videoElse = $timeLine-> videoFailures();

By using some of what Parker Dell supplied and a bit more trial and error
My Models Looks like
timeline
class timeline extends Model
{
protected $table ='timeline';
public $timestamps = false;
public function videos()
{
return $this->hasMany('App\timeline_videos','pid','id');
}
public function else()
{
return $this->hasMany('App\timeline_ect','pid','id');
}
}
timeline_ect.php ,I changed the name of the table
class timeline_ect extends Model
{
protected $table='timeline_ect';
public $timestamps = false;
public function timeline()
{
return $this->belongsTo('App\Models\timeline','pid','id');
}
}
timeline_videos
class timeline_videos extends Model
{
protected $table='timeline_videos';
public $timestamps = false;
public function timeline()
{
return $this->belongsTo('App\timeline','id','pid');
}
}
Then Lastly my Controller
$timeline = timeline::with('videos','else')
->orderBy('id','desc')
->limit(5)
->get();
So far no Problem query is correct.

Related

Laravel: Select from Database

in my Laravel App I have two tables:
Projects
- id
- user_id
- name
- etc...
Images
- id
- project_id
- url
How can I achieve it, to show all the Projects each user has and all the connected images (each project can have up to 20 images (stored in FTP) and Link in Field URL - the project_id from table "Projects" will be saved in field images.project_id)?
I learned, that I can show the projects like this:
$projects = DB::table('projects')->where('user_id','=',$user->id)->get();
and I tried with
$images = DB::table('images')->where('project_id','=',$projects->id)->get();
But I get an error message:
Property [id] does not exist on this collection instance.
What I am missing? Thank you for pointing me into the correct direction :-)
Kind Regards,
Stefan
For your question i suggest to use eloquent way like set up your models
class Project extends Model
{
public function images()
{
return $this->hasMany(\App\Models\Image::class, 'project_id');
}
public function user()
{
return $this->belongsTo(\App\Models\User::class, 'user_id');
}
}
class Image extends Model
{
public function project()
{
return $this->belongsTo(\App\Models\Project::class, 'project_id');
}
}
Now to find projects with their images you can query as
$projects = Project::with('images')->get();
Each object in $projects will have collection of their associated images.
To add filter for user you can use whereHas on relations
$projects = Project::with('images')
->whereHas('user', function ($query) use ($user) {
$query->where('id', '=', $user->id);
})->get();

Getting Form Data in edit-view with JTable which is joined?

i'm stuck with a problem of joined tables and retrieving Form-Data how it "should be" in best-practise-terms of Joomla!
I'm following the Joomla!-standards as far as my knownledge reaches, and the goal is to write this component "as if" it was native Joomla!-Code.
So what i have is the following COM_COMPONENT\models\release.php
<?php
defined('_JEXEC') or die;
class DojoMusicLibraryModelRelease extends JModelAdmin
{
public function getTable( $type = 'Releases', $prefix = 'DojoMusicLibraryTable', $config = array() )
{
return JTable::getInstance($type, $prefix, $config);
}
public function getForm( $data = array(), $loadData = true )
{
$options = array('control' => 'jform', 'load_data' => $loadData);
$form = $this->loadForm('releases', 'release', $options);
if (empty($form)) {
return false;
}
return $form;
}
protected function loadFormData()
{
$app = JFactory::getApplication();
$data = $app->getUserState('com_dojomusiclibrary.edit.release.data', array());
if (empty($data)) {
$data = $this->getItem();
}
return $data;
}
}
And in COM_COMPONENT\tables\releases.php
<?php
defined('_JEXEC') or die;
class DojoMusiclibraryTableReleases extends JTable
{
public $id;
public $title;
public $alias;
public $artist_id;
public $release_date_digital;
public $release_date_physical;
public $ean;
public $catalog_number;
public $promotional_text;
public $is_compilation;
public $format_id;
public $release_status;
// TODO: This tracklist should not be in this table, but only an id referring to it
public $tracklist;
public $created_at;
public $modified_at;
public $state;
public $publish_up;
public $publish_down;
public function __construct($db)
{
parent::__construct('#__dojomusiclibrary_releases', 'id', $db);
}
}
So now, as you can see from the comment in the latter code-example, the variable $tracklist is a field in the releases-table in my MySQL by now. As i got a "repeatable"-field-type, there is JSON inside of that field, and it works so far.
But the component is meant to hold another MySQL-table called "tracks", which holds all tracks of all releases and should be joined by a tracklist-id to the releases table, so that we have the following three tables:
releases (holds all the data, that is strictly bound to a single release/album/ep...)
tracklists (is an 1-to-m relation table, that has a tracklist_id, which is joined with the release and joins all single track_ids that belong to the tracklist)
tracks (holds all the track data, such as track_title, duration, genre and so on, while every track has an unique id, which can be joined to the tracklists)
As you can see this is getting more and more complex (especially if you consider that this is not the only part of the component, where this kind of joining tables for a single JForm will be needed).
Excerpt from the COM_COMPONENT\models\forms\release.xml
<!-- CATALOG NUMBER -->
<field name="catalog_number" type="text"
label="COM_DOJOMUSICLIBRARY_FORM_FIELD_CATALOG_NUMBER_LABEL"
description="COM_DOJOMUSICLIBRARY_FORM_FIELD_CATALOG_NUMBER_DESC" />
So now, as JForm seemingly expects something coming from the JTable since the release.xml binds the field-name to the naming of the variable in the JTable-Class, i do not really know how to deal with that, given that the data, that should be passed in one Form is coming from different tables.
So in summary i got different problems as far as i can see:
How can i manage to join tables for (best practice and right)
treatment of the JForm Standard in Joomla! ?
Since i use a repeatable-field-type to manage the tracklist, data will be stored into a JSON and saved to the database in only one field.
I need this repeatable solution since every release has n tracks with more than one information (track_no, title, genre...) and thanks to Joomla there is finally a native way to handle such cases.
BUT: Before saving them to the database the JSON must be split up into it's single values and be assigned to the proper fields in the tracks-table.
Okay... I know this is a huuuuuge question maybe... but since i'm totally stuck, I'd be happy about any advice for at least one of the issues :D
Thanks in advance :)

Include specific column from related-models table

Using Laravel 5.1: Given two related models, User and Item, with through table Item_User, how can I include a specific column from the through table, item_count using a with statement?
Item_User table:
Query:
$userGameProfile = User::with([
'items' => function($query) use ($profile_id) {
$query->with(['phrases'])->where('profile_id', '=', $profile_id);
}])->find($id);
Adding ->select('item_count') to this query only returns item count, and not the related item objects. Adding ->select('*') gets me the items and fields I want, but breaks the nested with(['phrases']) relationship I need to get related phrases to items.
I was told I should use withPivot, but I cannot find documentation or examples on how to use this.
Preferably, I'd like to add this to the relationship, rather than each query.
Models:
User:
public function items()
{
return $this->belongsToMany(Item::class, 'user_item');
}
Item:
public function users()
{
return $this->belongsToMany(User::class, 'user_item');
}
public function phrases()
{
return $this->belongsToMany(Phrase::class, 'item_phrase');
}
Phrase:
public function items()
{
return $this->belongsToMany(Item::class, 'item_phrase');
}
This article highlights how to include additional information from the pivot table.
In User model, I know I will always want to include item_count from user_items pivot table, so you can add withPivot to the relation to items:
public function items()
{
return $this->belongsToMany(Item::class, 'user_item')
->withPivot('item_count');
}
User now comes back with items and pivot data:

Using relationships in Laravel Eloquent with bridge table

I have an app that handles user info, and one of the pieces of data we collect is what school(s) they're attending. We have a User object, School object, and a UserSchool object.
This is the user_schools table:
user_id (int),school_id (int)
With the following records for instance:
100, 20
200, 500
200, 10
300, 10
I'm trying to get all schools for the current user (say user 200). This is my UserSchool object:
class UserSchool extends Model
{
var $table = 'user_schools';
function user() {
return $this->belongsTo('User');
}
function school() {
return$this->belongsTo('School');
}
}
In User I have the following relations defined:
public function schools()
{
return $this->hasManyThrough('School', 'UserSchool');
}
public function userSchools()
{
return $this->hasMany('UserSchool');
}
When I var_dump($user->schools) I get no results, even though I know it should be returning multiple Schools. What am I doing wrong? I'm sure this must have been asked before but I don't know what the actual term for this intermediate type of relationship is (bridge table? pivot table?).
Edit: Either way, most of the examples I've looked at haven't worked. I've also tried:
public function schools()
{
return $this->hasManyThrough('School', 'UserSchool', 'school_id');
}
In fact you don't need to have UserSchool object here for this relationship
For User model you can use create the following relationship:
public function schools()
{
return $this->belongsToMany(School::class, 'user_schools');
}
And now you can get schools of user using something like this:
$user = User::find(1);
foreach ($user->schools as $school)
{
echo $school->name;
}
This is standard many to many relationship

How Eloquent work with Relationship?

I'm new to laravel relationship so many apologizes if it's just dumb question. I'm using a pivot table named users_email on the project to get Emails of users. Pivot table contains the foreign key Uid and Email_id. Uid references users table
primary key and the same as Email_id. I can get the result while joining them using QueryBuilder.
$recent_inbox_email=DB::table('users_email')->
join('email','users_email.email_id','=','email.Id')->
join('users','users_email.Uid','=','users.Id')->
where('users_email.Uid','=',$Uid)->
where('email.draft','<>','true')->
where('email.trash','<>','true')->
where('email.status','=','unread')->count();
here's how I define the relationship in my models
public function getUid()//User Model
{
return $this->hasMany("User_Email",'Uid');
}
public function getEmId()//Email Model
{
return $this->hasMany("User_Email",'email_id');
}
//User_Email Model
public function email()
{
return $this->belongsTo('Email','Id','email_id');
}
public function user()
{
return $this->belongsTo('User','Id','Uid');
}
Now I want to query something like this using Eloquent
$query= select * from users_email inner join
email on users_email.email_id=email.Id
inner join users on users_email.Uid=users.Id
where users.Id=users_email.Uid limit 0,10
foreach($query as $emails)
{
echo $emails->f_name;
echo $emails->Message
}
DB designer Pic
Link to image
Thanks
There are no dumb questions. I'll try to give you an explanation! I'm not a pro, but maybe I can help.
Laravel uses some conventions that are not mandatory, but if you use them, things work like a charm.
For example, as a general recommendation, tables should be named in plural (your table users is ok. Your "email" table should be "emails"). The model, should be named in singular. This is User.php for table users, Email.php for table emails.
"The pivot table is derived from the alphabetical order of the related model names...", in this case "email_user". I repeat, you are not obliged to name them like this, as you can specify the table for the model setting the $table property in the model.
Once you have set up things like this, you only have to add this to your User model:
public function emails()
{
return $this->belongsToMany('Email');
}
And in your Email model:
public function users()
{
return $this->belongsToMany('User');
}
The "User" and "Email" between parentheses is the name of the related model.
And that's it. You can now do this:
$user = User::find(1);
foreach($user->emails as $email) {
echo $email->subject . '<br>';
echo $email->message . '<br>';
}
If you decide not to follow conventions, you can still use Eloquent relationships. You have to set up the relationship like this:
public function nameOfRelation()
{
return $this->belongsToMany('NameOfRelatedModel', 'name_of_table', 'foreign_key', 'other_key');
}
In the case of the User model for example:
public function emails()
{
return $this->belongsToMany('Email', 'users_email', 'Uid', 'email_id');
}
And in the email model, the other way round.
The answer got long! I didn't test the code, but this should give you an idea!
You can always check the official Laravel documentation, it is really helpful!
http://laravel.com/docs/4.2/eloquent
Hope I helped