Laravel nested cross database relation - laravel

Why set connection does not work in nested relation?
Follower.php
class Follower extends Model {
$connection = 'followers';
public function details() {
return $this->belongsTo(User::class, 'user_id');
}
}
User.php
class User extends Model {
$connection = 'users';
protected $withCount = ['notifications'];
public function notifications() {
return $this->setConnection('followers')->hasMany('App\Models\Notifications');
}
}
and the query:
Follower::query()->where('user_id', 1)->with('details')->get();
and it throws :
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'users.notifications' doesn't exist (SQL: select ` ....
But when I try this it works very well
User::with('notifications')->find(1);
Update
Notification.php
class Notification extends Model
{
protected $fillable = [
'user_id',
'builder',
'notification_type',
'comment_id',
'read_at'
];
}

This is a known issue with laravel since 2018, for more information see this thread , also there is a open pull request to fix this issue and will get fixed till next release
for now you can use hoyvoy/laravel-cross-database-subqueries package
install package using this
composer require hoyvoy/laravel-cross-database-subqueries
Follower.php
use Hoyvoy\CrossDatabase\Eloquent\Model;
class Follower extends Model {
$connection = 'followers';
public function details() {
return $this->belongsTo(User::class, 'user_id');
}
}
User.php
use Hoyvoy\CrossDatabase\Eloquent\Model;
class User extends Model {
$connection = 'users';
protected $withCount = ['notifications'];
public function notifications() {
return $this->setConnection('followers')->hasMany('App\Models\Notifications');
}
}
for every model you have add the default protected $connection

Related

How to display owner of a post in laravel admin list display?

public function index()
{
$query = Activity::orderBy('id','DESC')->with('provinces');
if(!Auth::user()->hasRole('Administer')){
$query=$query->where('province_id', Auth::user()->id);
}
$activities = $query->latest()->get();
return view('activity.index',compact('activities'));
}
How to display owner of a post in laravel admin list display?
My User Model
class User extends Authenticatable implements HasMedia
{
public function activities()
{
return $this->hasMany(Activity::class);
}
}
My Activity Model:
class Activity extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function provinces()
{
return $this->belongsToMany(Province::class);
}
}
My province Model
class Province extends Model
{
protected $fillable = [ 'title', 'post_id'];
public function activities()
{
return $this->belongsToMany(Activity::class);
}
public function user()
{
return $this->belongsToMany(User::class);
}
}
I want to show the content to the user by province.
And also the admin can see all the content.
please help me i am new in laravel
Based on your comment, you should change your province conditions to:
if (!Auth::user()->hasRole('Administer')) {
$query = $query->where('province_id', Auth::user()->province_id);
}
You have defined that each activity belongs to an user. So can access owner of each activity like this:
$activity->user->name;
And if your activity belongs to a province, you should define your relation in this way:
class Activity extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function province()
{
return $this->belongsTo(Province::class);
}
}
Also for your Province model:
class Province extends Model
{
protected $fillable = [ 'title', 'post_id'];
public function activities()
{
return $this->hasMany(Activity::class);
}
public function users()
{
return $this->hasMany(User::class);
}
}
And this is best practice to use eager loading for fetching related records. It will look like this one:
$query = Activity::with(['user', 'province'])->orderBy('id','DESC');
Also another hint: try to use better variable names. You can use $activities instead of $query.

Call to undefined relationship on model

We have the following class using $with:
class CargaHorasEmpleado extends Model
{
protected $table = "empleados_horas";
protected $with = ["tipoTarea", "proyecto", "empleado", "empleadoQueHizoLaCarga"];
public function tipoTarea()
{
return $this->belongsTo('App\TipoTarea', 'id_tipo_tarea', 'id')->withTrashed();
}
public function empleado()
{
return $this->belongsTo('App\Empleado', 'id_empleado', 'id')->withTrashed();
}
public function empleadoQueHizoLaCarga()
{
return $this->belongsTo('App\Empleado', 'id_empleado_cargo_hs', 'id')->withTrashed();
}
public function proyecto()
{
return $this->belongsTo('App\Proyecto', 'id_proyecto', 'id')->withTrashed();
}
}
This is the class TipoTarea
namespace App;
use Illuminate\Database\Eloquent\Model;
class TipoTarea extends Model
{
protected $table = 'tipos_tareas';
public $timestamps = false;
protected $fillable = [
'titulo', 'descripcion'
];
}
Thep page throws the error: "Call to undefined relationship [tipoTarea] on model [App\CargaHorasEmpleado]". That's the only relationship that's not working. The others are fine. What's wrong?
Well, isn't the relationship called "tipoTarea"? You wrote "tiposTarea"
The problem was that my class "TipoTarea" didn't use softdeletes. So the error was in using the "WithTrashed" method. The correct way is:
public function tipoTarea()
{
return $this->belongsTo('App\TipoTarea', 'id_tipo_tarea', 'id');
}

RelationNotFoundException Laravel

I'm facing a problem, as to why the relation is not getting connected.
vendor.php
class Vendor extends Model
{
public function internets()
{
return $this->hasMany('App\Internet');
}
}
internets.php
class Internet extends Model
{
protected $with=['vendor','coba'];
public function vendor()
{
return $this->belongTo('App\Vendor');
}
}
any one can help me?
it will be belongsTo
return $this->belongsTo('App\Vendor');
Try something like this
In your vendor
class Vendor extends Model
{
protected $table = 'Vendor Table Name';
protected $primarykey = 'Your Vendor Table primary Key';
public function internets()
{
return $this->hasMany(App\Internet::class, 'relational key');
}
}
And In your internet
class Internet extends Model
{
protected $with=['vendor','coba'];
protected $table = 'Internet Table Name';
protected $primarykey = 'Internet table primary key';
public function vendor()
{
return $this->belongsTo(App\Vendor::class, 'relation key');
}
}
I hope this will solve your problem let me know if this do the trick

Laravel: how to set connection for many to many relationship?

I have the models
class User extends Model
{
protected $connection = 'mysql';
public function areas()
{
return $this->belongsToMany(Area::class, 'user_areas');
}
}
class Area extends Model
{
protected $connection = 'oracle';
}
the user_areas table is searched on oracle, but this are on mysql.
How I can indicate the connection for the pivot table?
I found this partial solution and it has worked
class User extends Model
{
protected $connection = 'mysql'
public function areas()
{
$instance = new Area;
$instance->setConnection('mysql');
return new BelongsToMany($instance->newQuery(), $this, 'user_areas', 'user_id', 'area_id', 'areas');
}
}

Laravel belongsTo and hasMany relationship on same model

How do you apply belongsTo and hasMany relationship on same model?
For example, I have one User and one Project model. Now Project model has method user() and User model has projects() method.
Now I want a user to share projects with other users. So that I can have methods like users() in Project model and shared_projects() in User model.
How I can achieve that?
Here is my current Project model
class Project extends \Eloquent {
protected $fillable = [];
public function user() {
return $this->belongsTo('User');
}
}
And this my User model
class Project extends \Eloquent {
protected $fillable = [];
public function projects() {
return $this->hasMany('Project');
}
}
In this case, User and Project have Many-to-Many relationship because one user has many projects and one project belongs to many user. Therefore, you should create a third table (project_user) which connect User table and Project table in the database.
And you set Many-to-Many relation to User Model and Project Model.
class User extends Eloquent {
public function projects()
{
return $this->belongsToMany('Project');
}
}
In Project model
class Project extends Eloquent {
public function users()
{
return $this->belongsToMany('User');
}
}
Then you can do something like this
//users in the same project
$users = Project::find($id)->users;
Okay, so here it is how I solved it. I used pivot table as you suggested but I even added hasMany relationship like this way. I am still not sure what I am doing is perfectly correct but it worked. :)
class Project extends \Eloquent {
protected $fillable = [];
public function users() {
return $this->belongsToMany('User');
}
public function user() {
return $this->belongsTo('User');
}
}
And here is the key ingredient in User model
class User extends \Eloquent {
protected $fillable = [];
public function projects_owned() {
return $this->hasMany('Project', 'user_id');
}
public function projects() {
return $this->belongsToMany('Project');
}
}

Resources