Laravel 5 Polymorphic in Multiple Connection - laravel-5

I'm trying to setup a polymorphic relationship on multiple database on connection.
Let's say I have
Database A, Table users (id, email, password, userable_id,
userable_type)
Database B, Table companies (id, name, address, phone)
On each User and Company model, I also set each connection:
/* Database A */
protected $connection = 'database_a';
/* Database B */
protected $connection = 'database_b';
And for the relationship
/* Database A (User model) */
public function userable()
{
return $this->morphTo();
}
/* Database B (Company Model) */
public function user()
{
return $this->morphMany('user','userable');
}
And in my AppServiceProvider.php, I morphMap the user and vendor model:
Relation::morphMap([
'user' => \App\Models\V1\Shared\User::class,
'vendor' => \App\Models\V1\Training\Vendor::class
]);
This code will not work unless I set the userable relationship with connection:
public function userable()
{
return $this->setConnection('database_b')->morphTo();
}
In case, I want to add more user type and I have to use the new database, How do I use appropriate database/How do I make laravel to detect the connection automatically in morphTo without having to use setConnection()?

This is much late but I have faced recently the same problem, I am now using Laravel 5.5 and there I only had to use
protected $connection = 'db_names'
for both the models belonging to different databases - that actually worked like a charm.
I didn't have to use
$this->setConnection('database_b')->morphTo(), I just used $this->morphTo() :)

Related

How to override laravel model query?

I have a main model called User that returns all the users of the application.
There is a table called invites which manages the users invited to access the invitee panel. The invites table is thus linked to users:
So we have a general User model which handle all the users, and other two types of users:
Patient: user who invited the tenant
Tenant: user who has access to a list of associated patients
What I am trying to do is to fetch a patient list of a certain tenant (logged in user) using the eloquent relationship system, so I don't have to write a query for the join every time. Is it possible to do this?
At the moment, I tried this:
class Patient extends User
{
use HasFactory;
//protected $table = 'users';
public function getList()
{
return $this->belongsToMany(User::class, 'invites', 'id', 'user_id');
}
}
but of course this relationship not works because the query that should execute must be this:
SELECT u.*
FROM users u
INNER JOIN invites i ON i.user_id = u.id
WHERE i.tenant_id = 1
where id is the reference of the current user logged in which I retrieve using laratrust auth: auth()->user()->id.
Would be possible to return all the patients associated to the logged in user automatically? So simply calling:
Patient::query();
How can I achieve this?
To achieve that you should define relation and reverse many to many relation:
in your user model:
class Tenant extends User
{
use HasFactory;
protected $table = 'users';
public function patients()
{
return $this->belongsToMany(User::class, 'invites', 'tenant_id', 'user_id');
}
}
And in Patient model define reverse many to many relation by reverse belongToMany params :
class Patient extends User
{
use HasFactory;
protected $table = 'users';
public function tenants()
{
return $this->belongsToMany(User::class, 'invites', 'user_id', 'tenant_id');
}
}
To use the auth id for each model you have 2 option:
Option 1:
add column in users table that named user_type wich have type enum('tenant','patient') and depend user type use the appropriate model
Option 2:
by using custom auth guards , take look to this article
https://www.codecheef.org/article/laravel-8-login-with-custom-guard-example

Clarification with eager loading/mutators/accessors for laravel

I'm making a laravel app for work and I need to load all users with their attached role without any nesting of the roles. I used this tutorial for roles: https://medium.com/#ezp127/laravel-5-4-native-user-authentication-role-authorization-3dbae4049c8a . If I use public $with = ['roles']; on my User model it returns the entire role object within the user object and I need it to just return role:'role_name';
/**
* set up eloquent between roles/user
*
* #return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function roles()
{
return $this->belongsToMany(Role::class);
}
Above is in my User model and below is in my Role model to define the relationships.
/**
* provides a many-to-many relationship to User model
*
* #return User::class
*/
public function users()
{
return $this->belongsToMany(User::class);
}
I thought that by adding this to the User model:
protected $appends = ['role_name'];
public function getRoleNameAttribute()
{
return $this->attribute['name'];
}
it would return everything but all it does is create a role_name: 'user_name'; On the model. So I guess I realize I'm accessing just the Users table and not the Roles table in the DB, but again not really sure what to do. Any help would be greatly appreciated.
If for the purpose of convenience you need to access the role name directly from the model you should refer to the actual relationship data:
protected $appends = ['role_name'];
public function getRoleNameAttribute()
{
return $this->roles->pluck('name');
}
This should append the array of role names to your user model. It will be an array because roles seem to have a many-to-many relationship with the User model.
The issue is you're returning $this->attributes['name'] in the getRoleNameAttribute. You want the role names, so instead you'd do something like this:
If you want an array with the names:
return $this->roles()->pluck('name')
If you want the names as a string:
return array_implode(", ", $this->roles()->pluck('name')->toArray());

laravel use field in Eloquent model from another table

I have a model named "User". I want "Password" field from Eloquent from another table, and when user calls the user::all() method, all selected fields from different tables come in the result.
How can i do that?
Results are not displayed in with() .
my problem solved by using $appends in Eloquent model .
my code :
class User extends Eloquent {
protected $table = 'user';
protected $attributes = ['password'];
protected $appends = ['password'];
public function getPasswordAttribute()
{
return $this->getPAsswordMethod();
}
}
Your question is extremely board and borderline unanswerable but I will give you a board solution.
You are able to establish relationships to other tables via the Model objects you create. Lets pretend you have a Password table which belongs to the User.
User model:
public function password()
{
return $this->hasOne(Password::class, 'FK', 'PK');
}
You can now do User::with('password')->get(['FieldName']); and this will give you all of the passwords which have the above relationship to a user.

Laravel Eloquent BelongsToMany multiple databases

I have two databases ("internal" and "external") and I would like to create a BelongsToMany relation between them. The problem, how do I specify in which database the relation_table is stored?
In my current case, I have some users that I would like to connect to some objects from an external database.
User:
public function objects() {
return $this->belongsToMany('\App\Object', 'user_object_relation');
}
Object:
protected $connection = 'mysql_data';
protected $table = 'objects';
protected $primaryKey = 'ObjectID';
Eloquent now is assuming my user_object_relation table in the mysql_data (external) database, however I've created this in the "internal" database.
Q: How do I tell eloquent that the relation table is not in the external table?
// edit:
with return $this->belongsToMany('\App\Object', 'internal.user_object_relation');, I receive an access denied error because the "external" database user has no access to the internal ;)

Laravel 4 - Display username based on ID

I have a posts and a users table.
In the posts table, i have a posts_author which is the ID of the user from the users table.
Is there an easy way to display the email address of the user, which is in the users table?
Cheers,
As long as you've set your relationships up it should just be a simple query.
http://laravel.com/docs/eloquent#relationships
Look at the one to many relationships.
(1 User, Multiple posts)
Remember to set the inverse of the relationship up also
If your model has the right relationships then should be as simple as $post->author->email().
You must tweak the author relationship because Eloquent assumes the key will be named author_id.
// Post
public function author() {
return $this->belongsTo('Author', 'posts_author');
}
// Author
public function posts() {
return $this->hasMany('Post');
}
Remember to use eager loading in case you are retrieving emails from more than one post object, or you will end up with n+1 queries.
Providing that you've configured the relationships properly, it should be pretty easy.
Post Model:
class Post extends Eloquent
{
protected $table = 'posts';
public function author()
{
return $this->belongsTo('User', 'posts_author');
}
}
Then User Model:
class User extends Eloquent
{
protected $table = 'users';
public function posts()
{
return $this->hasMany('Post', 'posts_author');
}
}
Then when loading the post you can do the following.
$post = Post::with('author')->find($id);
This will tell Eloquent to join on the users table and load the user data at the same time. Now you can just access all of the user information like this:
$post->author->username;
$post->author->email;
$post->author->id;
// etc etc
Obviously this is just a skeleton, but the assumption is that you have the rest setup.

Resources