Fetching Relationship Model Data - laravel

I have the Below Table Structure
Users table
id- integer
name-string
Casefiles table
id- integer
user_id- foreign_key
name-string
Followups table
id- integer
date- date
casefile_id-foreign_key
I'm using the below Relationship between this models
User.php
public function casefiles()
{
if ($this->hasRole(['sales_executive'])) {
return Casefile::where('user_id', $this->id);
}
}
Casefile.php
public function user()
{
return $this->belongsTo('App\User');
}
public function followups()
{
return $this->hasMany('App\FollowUp');
}
Followup.php
public function casefile()
{
return $this->belongsTo('App\Casefile');
}
I want to fetch Users followups directly. How can i achive this ?

you need to use hasManyThrough() in your User.php you can add this,
public function followUps()
{
return $this->hasManyThrough('App\FollowUp','App\Casefile');
}
then you can normally call the followups using User::with('followUps')->find(1)->followUps
I have noticed that you are checking role in your relationship $this->hasRole(['sales_executive'] this may occur error as you are not if the statement is false. I think you take another approached and handle that as well. for more information on hasManyThrough prefer this link

This should be the case for a HasManyThrough Relationship.
In your case it should be
// Followups migration
Schema::create('followups', function (Blueprint $table) {
$table->bigIncrements('id');
$table->date('date');
$table->unsignedBigInteger('casefile_id')->nullable();
$table->timestamps();
$table->foreign('casefile_id')
->references('id')
->on('casefiles');
});
// Casefile migration
Schema::create('casefiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->unsignedBigInteger('user_id')->nullable();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users');
});
// User.php
public function followups() {
return $this->hasManyThrough(FollowUp::class, Casefile::class);
}
// YourController.php
$user = User::all()->first();
dd($user->followups);

Related

Laravel: cannot insert into many to many relationship

i hope you're having a good day.
so i have this ManyToMany relationship where a user can apply to multiple jobs, and a job can have multiple applicants (users).
here is the table schema
Schema::create('applicant_job', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('job_id');
$table->unsignedBigInteger('applicant_id');
$table->unique(['job_id', 'applicant_id']);
$table->foreign('job_id')
->references('id')
->on('jobs')
->onDelete('cascade');
$table->foreign('applicant_id')
->references('id')
->on('default_users')
->onDelete('cascade');
});
and here is the model code.
DefaultUser.php
class DefaultUser extends Model
{
public function user()
{
return $this->morphOne(User::class, 'userable');
}
public function applications()
{
return $this->belongsToMany(Job::class, 'applicant_job', 'job_id', 'applicant_id');
}
}
and Job.php
class Job extends Model
{
public function owner()
{
return $this->belongsTo(BusinessUser::class, 'business_user_id');
}
public function applicants()
{
return $this->belongsToMany(DefaultUser::class, 'applicant_job', 'applicant_id', 'job_id');
}
}
everything seems ok and find, however when i try to save ( a user applying to a job), i get the following error
i'm doing so inside ApplyToJobController.php
class ApplyToJobController extends Controller
{
public function store(Job $job, Request $request) {
$default_user = auth()->user()->userable;
$job->applicants()->attach($default_user->id);
return redirect("/en");
}
}
and, Thank you very much for your answers.
EDIT
i have changed the column names to this
Schema::create('applicant_job', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('job_id');
$table->unsignedBigInteger('default_user_id');
$table->unique(['job_id', 'default_user_id']);
$table->foreign('job_id')
->references('id')
->on('jobs')
->onDelete('cascade');
$table->foreign('default_user_id')
->references('id')
->on('default_users')
->onDelete('cascade');
});
it made it work, im curios any idea why?
Try to switch the order of the foreign keys in the applicants relation declared in the Job model like the example below :
public function applicants()
{
return $this->belongsToMany(DefaultUser::class, 'applicant_job', 'job_id', 'applicant_id');
}

laravel eloquent relation one to one

I have a Laravel migration like this
usergroups:
Schema::create('usergroups', function (Blueprint $table) {
$table->integer('id')->primary();
$table->string('name');
$table->string('slug');
});
users:
Schema::create('users', function (Blueprint $table) {
$table->integer('nik')->primary();
$table->string('name');
$table->string('username');
$table->string('password');
$table->string('telp', 15);
$table->integer('usergroup_id');
$table->rememberToken();
$table->timestamps();
});
Schema::table('users', function ($table) {
$table->foreign('usergroup_id')->references('id')->on('usergroups')->onDelete('cascade');
});
User model
public function group()
{
return $this->belongsTo(Usergroup::class, 'id');
}
Usergroup model
public function user()
{
return $this->hasMany(User::class, 'usergroup_id');
}
I get blank data with this
$petugas = User::find(1);
return $petugas->group;
anyone help me, please...
This is not a One to One relationship i.e (user has one phone and one phone belongs to one user)
A group has many users in this case, One to Many relationship
You're migrating the users table twice, move the foreign key to the migration
Schema::create('users', function (Blueprint $table) {
$table->integer('nik')->primary();
$table->string('name');
$table->string('username');
$table->string('password');
$table->string('telp',15);
$table->integer('usergroup_id');
$table->foreign('usergroup_id')->references('id')->on('usergroups')->onDelete('cascade');
$table->rememberToken();
$table->timestamps();
});
Hope this helps
First of all, this is not a One to One relationship. This is a One to Many relationship. The relation you have build in wrong way according to migration files.
The relation code block should look like this.
public function group()
{
return $this->hasMany(Usergroup::class);
}
public function users()
{
return $this->belongsTo(User::class);
}
Some more info:
In your scenario there might be two possible fact.
A user has many groups, but a group is belongs to only one
user.
A group has many users but a user is belongs to only one
group.
Fact 1: In this case the foreign key column should place in groups table. To follow the convention make the foreign column name user_id in groups table. And the code should look like this
public function groups()
{
return $this->belongsTo(Usergroup::class);
}
public function user()
{
return $this->hasMany(User::class);
}
Fact 2: In this case the foreign key column should place in users table. To follow the convention make the make the foreign column name group_id in users table And the relation code should look like this
public function group()
{
return $this->hasMany(Usergroup::class);
}
public function users()
{
return $this->belongsTo(User::class);
}
i got it...
this on user model
public function group()
{
return $this->belongsTo(Usergroup::class,'usergroup_id');
}
and this on usergroup model
public function user()
{
return $this->hasMany(User::class,'usergroup_id');
}

Laravel 5.4 belongsToMany relationship returns empty

In Laravel 5.4 I'am trying to set up a Many To Many Relation. but the belongsToMany returns empty! Here's my migrations and models.
botusers Table:
public function up()
{
Schema::create('botusers', function (Blueprint $table) {
$table->increments('id');
$table->integer('t_id');
$table->string('first_name');
$table->string('last_name');
$table->string('username');
$table->string('mobile');
$table->timestamps();
});
}
candidates Table:
public function up()
{
Schema::create('candidates', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('token');
$table->string('degree');
$table->integer('age');
$table->text('desc');
$table->string('photo_url');
$table->string('cv_url');
$table->timestamps();
});
}
Third table, botuser_candidate Table:
public function up()
{
Schema::create('botuser_candidate', function (Blueprint $table) {
$table->integer('botuser_id');
$table->integer('candidate_id');
});
}
and the votes() method in Botuser Model:
public function votes()
{
return $this->belongsToMany(Candidate::class)->get();
}
When I fire the votes() method returns an empty array. and I also tested bellow method too,
public function votes()
{
return $this->belongsToMany(Candidate::class,'botuser_candidate','botuser_id','candidate_id')->get();
}
What I missed here? What should I do?
Edit:
I also added the foreign keys to the relation but the result is still same!
I would suggest you remove the get() method on the belongsToMany
Then query the database with
$c=new App\Candidate;
$c->with('votes')->get()
if you still want to use $c->votes() then you would have to do some changes to your functions. Lets use scope to achieve it.
public function candidates()
{
return $this->belongsToMany(Candidate::class,'botuser_candidate','botuser_id','candidate_id');
}
public function scopeVotes($query)
{
return $query->with("candidates")->get();
}
Then now we can call $v->votes() and it should return all your record.
Calling get() directly on belongsToMany method will return empty array.

Get data from 2 tables connected using a pivot table (Laravel 5.3)

How to get data from 2 tables connected using a pivot table ? for example, in my case I have users table connected to journal table using a pivot table (penulis table). Now I want to get journals data that belonged to specific user. I tried this :
$journal_list = DB::table('journal')->where('id_user', '=','id_journal')->orderBy('id', 'desc')->paginate(20);
That code above doesn't work. Below are my migrations :
Users table :
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('username')->unique();
$table->string('userslug');
$table->string('nameslug');
$table->string('email')->unique();
$table->string('phone')->nullable();
$table->string('address')->nullable();
$table->string('password');
$table->rememberToken();
$table->enum('level', ['admin', 'author']);
$table->timestamps();
});
}
Journal table :
public function up() {
Schema::create('journal', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 255);
$table->text('abstract');
$table->text('file');
$table->integer('id_edition')->unsigned();
$table->string('journalslug');
$table->timestamps();
});
}
Penulis table (the pivot table)
public function up()
{
Schema::create('penulis', function (Blueprint $table) {
// Create tabel penulis
$table->integer('id_user')->unsigned()->index();
$table->integer('id_journal')->unsigned()->index();
$table->timestamps();
// Set PK
$table->primary(['id_user', 'id_journal']);
// Set FK penulis --- user
$table->foreign('id_user')
->references('id')
->on('users')
->onDelete('cascade')
->onUpdate('cascade');
// Set FK penulis --- journal
$table->foreign('id_journal')
->references('id')
->on('journal')
->onDelete('cascade')
->onUpdate('cascade');
});
}
View composer :
public function boot()
{
View::composer('user/show', function ($view) {
$journal_list = User::where('id', $user_id)->with('journal')->first();
$view->with('journal_list', $journal_list);
});
}
If you want to use Eloquent, you should setup belongsToMany() relation first:
class User extends Authenticatable
{
public function journals()
{
return $this->belongsToMany('App\Journal');
}
Then use eager loading to load the data:
User::where('id', $userId)->with('journals')->first();
If you don't want to use Eloquent and just need journals:
$journal_ids = DB::table('penulis')->where('id_user', $userId)->get(['id_journal'])->toArray();
$journal_list = DB::table('journal')->whereIn('id', $journal_ids)->paginate(20);
Or do the same by using join().
Why not make use of the Eloquent if you are using Laravel
First define the relations in your models
class User extends Model {
public function journal(){
return $this->belongsToMany('App\Journal', 'penulis', 'id_user', 'id_journal');
}
}
class Journal extends Model {
public function user(){
return $this->belongsToMany('App\User', 'penulis', 'id_journal', 'id_user');
}
}
Of course you need to define the table and fillables in your model with table name and table columns respectively.
And to get the specific data related to users you can use eloquent,
User::with('journal')->paginate(20);
This will load 20 users(paginated) with related journal data.
To know further about the eloquent relationships, take a look at this link.
Hope it solves your problem.

One to Many not working on Laravel Eloquent

I have three models that are related. First I have User that belongs to a Role. On the other hand, Role has many roles. Role belongs to many permissions and Permissions belongs to many Role. I am using the AuthServiceProvider as suggested by jeffrey way of laracast. But the problem now, when I want to fetch all the permissions of a User I am having error which is, "Call to a member function getKey() on boolean". Can someone please help me on this. Please refer to the codes below.
User.php
public function role()
{
return $this->belongsTo('App\Role');
}
public function assignRole($role)
{
return $this->roles()->save(
Role::whereName($role)->firstOrFail()
);
}
public function hasRole($role)
{
if(is_string($role)){
return $this->role->contains('name', $role);
}
return !! $role->intersect($this->role)->count();
}
Role.php
class Role extends Model
{
public function users()
{
return $this->hasMany('App\User');
}
public function permissions()
{
return $this->belongsToMany('App\Permission');
}
public function givePermissions(Permission $permission)
{
return $this->permissions()->save($permission);
}
}
Permission.php
class Permission extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
AuthServiceProvider
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
//get all permissions
foreach ($this->getPermissionTo() as $permission ) {
$gate->define($permission->name, function($user) use ($permission){
return $user->hasRole($permission->roles);
});
}
}
public function getPermissionTo()
{
return Permission::with('roles')->get();
}
and lastly, heres the user table that has a foreign key of role_id
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('role_id')->unsigned();
$table->string('id_no')->unique()->index();
$table->string('u_first_name');
$table->string('u_middle_name');
$table->string('u_last_name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
roles table
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('label')->nullable();
$table->timestamps();
});
permissions table
Schema::create('permissions', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('label')->nullable();
$table->timestamps();
});
permission_role table
Schema::create('permission_role', function (Blueprint $table) {
$table->integer('permission_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->foreign('permission_id')
->references('id')
->on('permissions')
->onDelete('cascade');
$table->foreign('role_id')
->references('id')
->on('roles')
->onDelete('cascade');
$table->primary(['permission_id', 'role_id']);
});
In the line: return !! $role->intersect($this->role)->count();, the part that says $this->role is probably not returning a collection, which is why you're getting this error. In Collection.php there's a method that iterates through all the items in a collection you send through the intersection method that gets the primary key of it. Because you're not sending a collection to the intersect() method, it tries to use the method getKey() in a boolean. Try:
return !! $role->intersect($this->role->get())->count();

Resources