Laravel Eloquent BelongsToMany multiple databases - laravel

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 ;)

Related

Fetch relational object from cache

I have below code that fetches users and relational role object for each user.
$query = (new UserModel())->newQuery();
$query->with("Role");
$data = $query->get(["UserName", "EmailAddress", "User_ID"]);
I have 3 roles present in database and they are in cache.
Is there any way to change this line of code: $query->with("Role"); such that while fetching the users each time, it will not need to fetch roles from database.
Maybe you can hook into the Retrieved event from Eloquent. When retrieving the model from the Database you can fetch the role from the cache and set it on the model. Perhaps that could be a solution for you?
Take a look at the Laravel Docs on eloquent events here: https://laravel.com/docs/5.6/eloquent#events
Maybe this will work out something for you, add this to your model class:
/**
* Boot the model.
*/
protected static function boot()
{
parent::boot();
static::retrieving(function ($user) {
$user->fetchFromCache("Role"); //replace this line with however you could fetch it from the cache
});
}

Many-to-many withouth relations (Laravel)

I have two application, in two different server.
In the first Laravel application I have my User model, and in the secound application I have my Blog model.
There is a many-to-many relationship between them, a user can have multiple blogs, and one blog can belongs to many user.
They have two different database, but everything is built like its only one app in one server.
They have a REST API, and its communicating between them. The problem is, I cant set up real relations between them (like belongsToMany in the Eloquent Model), and I can't list User's blogs.
Is there a way to copy the "User::blogs()" relation function, with some query work on Blog:: class? For e.g. select all blogs where user_id is equal to 1 in the pivot table?
<?php
class User extends Model{
protected $connection = 'Your Connection';
public function blogs(){
return $this->belongsToMany(Blog::class);
}
}
Blog.php
class Blog extends Model{
protected $connection = 'Your other connection';
public function users(){
return $this->belongsToMany(User::class);
}
}
You can set the multiple connections in your database.php and assign each model a different connection.
I am assuming that you have a user_blogs table. some where
hope this helps.
I found it, like this:
Blog::join('blog_user', 'blogs.id','=','blog_user.blog_id')->where('blog_user.user_id', '=', $this->userId)->get();

Eloquent whereHas Requires from() when Using Different Connections

I have two models - User and Announcement, and they exist on two separate connections - mysql and intranet respectively. The User model hasMany Announcements and the Announcement belongsTo a single User.
In the Announcement model I have protected $connection = 'intranet' and in the User model I have protected $connection = 'mysql'. Originally I wasn't specifying the $connection property on the User model as it is the default for the application but added it in for testing.
Doing any sort of query works normally. As an example these work:
User::find(1)->announcements()->where('name', 'something')->get()
Announcement::find(2)->user
However, when using whereHas on the Announcements model I get the following SQL Error: Base table or view not found: 1146 Table 'intranet.associate' - associate being the User's table and intranet being the database connection specified in the Announcement model.
While I did find an answer to the question here. I am curious, though, as to why you're required to use ->from(..). Is this intended functionality? I could not find anything in the documentation about using from().
As a side note I was able to fix this "issue" by assigning the $table property in the __construct method in the User model:
__construct(array $attributes = []) {
$this->table = env('DB_DATABASE').'.associate';
}
env('DB_DATABASE') being the default connection's database.

Laravel 5 Polymorphic in Multiple Connection

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() :)

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.

Resources