database relation between two different server - mysql

I have two servers and both of them contain several tables. Many of them contain relations. Now I need to join those tables and fetch data. I have no clue how to write this sort of query. Currently, I'm working in Laravel. Any suggestions will help me.
Thanks in advance.

If you want to use model relationships you can add connection and table field in your model;
class User extends Model {
public $connection = 'firstconnection';
public $table = 'users';
...
public function comments() {
return $this->hasMany(Comment::class);
}
}
class Comment extends Model {
public $connection = 'secondconnection';
public $table = 'comments';
...
}
You can define connections in your config/database.php, default connection is mysql.
If you write raw queries you can use full table path (specify database):
SELECT * FROM db1.users JOIN db2.comments ON db1.users.id = db2.comments.user_id;
Note: you must have enough privileges on both tables to join and select data. If you use exists, has or semething like that where ORM needs to join two table.
Hope this helps you

Related

problem with Using pivot table with Eloquent and Laravel

Here is my problem. I have a table called user and table called skills, also I have a pivot table that connects these two called EmployeeSkill. I am trying to fetch the skills that belong to the user but when i use tinker it returns Base table or view not found: 1146 Table 'pfe_sirh_db.skill_user' doesn't exist (SQL: select skills.*, skill_user.user_id as pivot_user_id, skill_user.skill_id as pivot_skill_id, skill_user.employee_id as pivot_employee_id from skills inner join skill_user on skills.id = skill_user.skill_id where skill_user.user_id = 1)' and am using swagger by the way it returns this "withTimestamps": false
class User extends Authenticatable{
protected $table = "users";
public function skills()
{
return $this->belongsToMany(Skill::class);
}
}
and
class Skill extends Model
{
public function User()
{
return $this->belongsToMany(User::class);
}
}
and the pivot table
class EmployeeSkill extends Model
{
protected $table = "employee_skills";
protected $fillable = [
'employee_id', 'skill_id', 'note'
];
}
Your pivot table should be named skill_user (singular) following the model name they belong to. And you don't need a EmployeeSkill model for this relation to work, you only need the table.
As said in the documentation:
to determine the table name of the relationship's joining table, Eloquent will join the two related model names in alphabetical order. However, you are free to override this convention. You may do so by passing a second argument to the belongsToMany method
And then you should exclude this line:
protected $table = "employee_skills";
change your table name to skill_user
And in your pivot table you should use user_id as a foreign key
You can retrieve all skills from a user by doing this:
$user = User::find(1);
$user->skills();
This will give you all the skills from the user with the id 1
Be aware that you can use any table name and any foreign key name but if you do that you need to specify the names on the relations. So i recommend you doing what i 've told you, since is the standard way

Joining Two Tables to a Reference Table Laravel

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.

Laravel 5 Read Only View Model with polymorphic Relationship

Sometimes we use MySql Views to organize related tables to make it easier to search and sort. For example if you have Posts with a Status, and a Source.
Post
subject
body
source_id
status_id
Status
id
label
other_field
Source
id
label
other_field
View
create view read_only_posts as
SELECT statuses.label as status, sources.label as source, posts.*
from posts
left join statuses on statuses.id = posts.status_id
left join sources on sources.id = posts.source_id
Then we have the Post model and an extra model:
// Post.php
class Post extends Model
{
//
}
// ReadOnlyPost.php
class ReadOnlyPost extends Post
{
protected $table = 'read_only_posts';
}
This is nice because now you can directly sort or filter on Status or Source as a string not the id's. You can also include the 'other_field'.
But we have a problem that I need help with. If you have a polymorphic many-to-many relationship on Posts, I can't get it to work on the read only version. For example if you have polymorphic tags:
// Post.php Model
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
The problem is when you filter a post (using the read only model) with a specific tag you get sql like this:
select count(*) as aggregate from read_only_posts where exists (select * from tags inner join taggables on tags.id = taggables.taggable_id where read_only_posts.id = taggables.taggable_type and taggables.taggable_type = 'read_only_posts' and label = 'test')
As you can see the problem is the taggables.taggable_type = 'read_only_posts'.
I can't find a way to override the morph type for a model. (I am on laravel 5.4 and the MorphClass isn't there anymore). The morph map is an associative array so you can't do this:
// AppServiceProvider
public function boot()
{
Relation::morphMap([
'posts' => Post::class,
'posts' => ReadOnlyPost::class, <--- Can't do this
My stupid fix is when I attach a tag to a post I also attach it to ready_only_posts, which is kind of a mess.
Anyone else uses Views for read only models? Anyone have a better way to overriding the many to many polymorphic type for a specific model?
Looking at the code, I believe this might work.
class ReadOnlyPost extends Posts
{
public function getMorphClass() {
return 'posts';
}
}
In theory you should need to have the Posts model/table listed in the morph map, since the system will auto generate the type of "posts" for it based on naming.

MySQL/Eloquent belongsToMany relation - two tables same pivot table allowed?

Is it allowed to have two tables, each with a belongsToMany() relation to each other, using the same pivot table?
Here is my User table:
And here is my Org table:
And here is the pivot table:
Here is the Eloquent User.php model:
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model {
protected $table = 'users';
public $timestamps = true;
use Authenticatable;
use SoftDeletes;
protected $dates = ['deleted_at'];
public function orgs()
{
return $this->belongsToMany('App\Org', 'org_user', 'org_id', 'user_id')->withPivot('role_id');
}
}
And here is the Eloquent Org.php model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Org extends Model {
protected $table = 'orgs';
public $timestamps = true;
use SoftDeletes;
protected $dates = ['deleted_at'];
public function users()
{
return $this->belongsToMany('App\User', 'org_user', 'org_id, user_id')->withPivot('role_id');
}
}
Is it OK to do this? (i.e. use a shared pivot table) Does anyone with experience foresee any issues here? Or maybe someone could comment on standard practice/share some insights?
Absolutely you can! This is the beauty of a many to many relationship, in fact the example at http://laravel.com/docs/4.2/eloquent#many-to-many has the User and Role classes both set with belongsToMany. Thought being in that case (and sounds like in yours as well) that a user can have multiple roles and each role can be associated with multiple users.
Regarding your last two questions, the only part that gave me pause is the use of a role_id within the pivot table. The code you provided doesn't go into detail on what purpose that serves. As long as the User would only ever have one role associated with an Org this is fine, but if it could ever be more than one I would recommend another table to hold that User to Org role 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