Wrapper for belongsTo returns null - laravel

2 tables - client and client_status
Table client:
id
client_status_id
name
This table contains 1 record with client_status_id and name filled.
Table client_status:
id
name
This table also not empty
Models for these tables:
class Client extends Model {
public function status() {
return $this->belongsTo(ClientStatus::class);
}
}
and
class ClientStatus extends Model {
protected $table = 'client_status';
public function clients() {
return $this->hasMany(Client::class);
}
}
When I assign $client somewhere in ClientController:
$client->name contains real client name
$client->status == null, so, I can't get $client->status->name (name of client status). Why and how to change?

The relationship is wrong, the user must have the status as has one, and the status belongs to user.
also from my opinion i would rather to save the user id, in the status table better. and it'll be much simple.

Related

I want to make many to many relationship using laravel Model

I am trying to make many to many relationships b/w three table I don't know how to make that please confirm me my relationship correct or not.
Project table
id | name
user table
id | name
project_assign
id | user_id | project_id
User Model
public function project_assign()
{
return $this->belongsToMany('App\Project_assign','project_assign','user_id','id');
}
project_assign Model
public function user()
{
return $this->belongsToMany('App\User','Project_assign','user_id','id');
}
Project Model
public function project_assign()
{
return $this->belongsToMany('App\Project_assign','project_assign','project_id','id');
}
you don't need to make a relation in project_assign model. only Project and User will have relation,
Project Model
public function users(){
return $this->belongsToMany('App\User','project_assign','project_id','user_id');
}
User Model
public function projects(){
return $this->belongsToMany('App\Project','project_assign','user_id','project_id');
}
In controller you can get like this
User::with('projects')->get();
Project::with('users')->get();

Laravel 6: Fetching data from multiple pivot tables

I have a funds table that contains funds that are associated with different faculties, institutes, initiatives etc. A fund belongs to many faculties and faculties could have many funds.
I also have a many to many relationship between users and faculty table to make sure that a user can only see the funds associated with specific faculties.
funds table
--------------------
id
name
...
faculties table
--------------------
id
name
...
faculties_funds table
---------------------
id
faculty_id
fund_id
users table
---------------------
id
fname
...
faculties_user
--------------------
id
faculty_user
user_id
Here is how I have defined my relationships:
class Fund extends Model
{
public function faculties(){
return $this -> belongsToMany('App\Faculty');
}
}
class Faculty extends Model
{
public function funds(){
return $this -> belongsToMany('App\Fund');
}
public function users(){
return $this -> belongsToMany('App\User');
}
}
class User extends Model{
public function faculties(){
return $this -> belongsToMany('App\Faculty');
}
}
What I need is to be able to fetch all the funds associated with the faculty that the authorized user is mapped to. I tested the relationships individually and they all work and I can dd the response that also has a relationship array with pivot information but I am somehow not able to get the funds that I want.
Any help would be appreciated in terms of writing a query to get the results preferably without using the raw queries or if I need to redo my database structure.
Here is my code so far:
public function index()
{
$user = Auth::user();
if(Auth::user() -> role == 'superadmin'){
return view('funds.index')
-> with('funds', Fund::all());
}else{
dd( Auth::user() -> faculties); //I can see the faculties associated and also
dd( Auth::user() -> faculties() -> funds ); //doesnt work
}
}
DD Response
Your table naming convention is not as per what Laravel expects: https://laravel.com/docs/7.x/eloquent-relationships#many-to-many
This modified code should return your funds as expected:
class Faculty extends Model
{
public function funds(){
return $this -> belongsToMany('App\Fund', 'faculties_funds', 'falculty_id', 'fund_id');
}
}
class User extends Model{
public function faculties(){
return $this -> belongsToMany('App\Faculty','faculties_user');
}
}
And then call
dd(Auth::user()->with('faculties.funds');

Laravel - Eloquent Relationship hasMany but also hasOne?

I've been all over the web and struggling with this for around 2 hours.
I have a USER model, a RUN model and a TIME model.
In the real world the user is in a race and gets their time entered in the database along with a USER_id and a RUN_id.
A user should only be able to have one row in the TIMES table for each RUN_id - if that makes sense!
Is this something I need to manage at the controller level? Or is there a relationship I can setup to ensure that a duplicate entry of this style can not enter the database?
Database structure at present:
USERS:
name
RUNS:
name
TIMES:
time
user_id
run_id
The Models:
USER:
public function times()
{
return $this->hasMany(Time::class);
}
RUN:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Run extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function times()
{
return $this->hasMany(Time::class);
}
}
TIME:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Time extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function run()
{
return $this->belongsTo(Run::class);
}
}
You can add a unique key constraint on the times table to enforce unique combinations of user_id and run_id
$table->unique(['user_id, 'run_id']);
To validate uniqueness at the application level, we can also add a constraint to the form validation. Assuming that you are passing both user_id and run_id in the request to create a new time, you can add the following to a form request
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'user_id' => Rule::unique('times')->where('run_id', $this->input('run_id'))
];
}
public function messages()
{
return [
'user_id.unique' => 'A user may only have 1 time entry per Run'
];
}
This will enforce the user_id is unique in the times table, filtered by that run id. The messages function also returns a more useful error message, since "user_id must be unique" is unhelpful in this situation.
This answer should supplement the accepted answer. You should still define the pair of user_id,run_id as a unique key.
However, in your case user and run have an N-N relationship with times as a pivot table. You should code it as such.
User
public function runs()
{
return $this->belongsToMany(Run::class, 'times')->withPivot('time');;
}
Run:
public function users()
{
return $this->belongsToMany(User::class, 'times')->withPivot('time');
}
Then you can retrieve them as:
$runs = User::find($userId)->runs; // Collection of all runs a user participated in
// $runs[X]->pivot->time has the time
You can check the documentation for more info

Laravel hasManyThrough getting through another model

I have this 3 tables. I would like to get the employee name who created the client
I have tried this
class LeadsModel extends Eloquent
public function researcher_name()
{
$user = $this->belongsTo('users','id','user_id');
return $user->getResults()->belongsTo('employees','id','employee_id');
}
But it returns an error:
"message":"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'employees.employee_id' in 'where clause' (SQL: select * from `employees` where `employees`.`employee_id` in (4))"}}
when I switch the id and employee_id, it does not return any relationship for users and employees.
Basically, I need to get the clients with the employee's name who created it.
Assuming relationships:
Client belongsTo User
User belongsTo Employee
simply call this:
$client->user->employee;
Given your schema, here are the relations you need in order to get an Employee related to particular Client (through User):
// Client model
public function user()
{
return $this->belongsTo('User');
}
// User model
public function employee()
{
return $this->belongsTo('Employee');
}
then simply call this:
$client = Client::find($someId);
$client->user; // single user related to the client
$client->user->employee; // single employee related to the user
You might want to check if given relation exists first:
// just an example, don't write it this way ;)
if ($client->user) { // user is not null
if ($client->user->employee) { // employee is not null as well
$client->user->employee->name; // name = field on the employees table
}
}
You need a Has Many Through relation.
Add the relationship in your Employee's model called clients:
public function clients()
{
return $this->hasManyThrough('App\Client', 'App\User');
}
And then you can use it like below:
Employee::first()->clients()->get();

laravel display only specific column from relation

I have read a few topics about this, but they managed to solve my problem partially ...
this is my controller
class DeskController extends BaseController{
public function getDeskUsers($deskId){
$user = DeskUserList::where(function($query) use ($deskId){
$query->where('deskId', $deskId);
})->with('userName')->get(array('deskId'));
if (!$user->isEmpty())
return $user;
return 'fail';
}
this is the model
class DeskUserList extends Eloquent {
protected $table = 'desk_user_lists';
public function userName(){
return $this->belongsTo('User', 'userId')->select(array('id','userName'));
}
}
the method getDeskUsers may returns ALL the DeskUserList table records, related with the User table record (on deskUserList.userId = User.id).
practically I want each record returned is composed of:
DeskUserList.deskId
User.userName
eg. [{"deskId":"1","user_name":antonio}]
What i get is
[{"deskId":"1","user_name":null}]
As you can see the user name is a null value...
BUT
if I edit my controller code:
->with('userName')->get(array('userId')); //using userId rather than deskId
then i get
[{"userId":"2","user_name":{"id":"2","userName":"antonio"}}]
By this way I still have two problem:
the userId field is twice repeated
I miss the deskId field (that I need...)
hope be clear, thanks for your time!
You need belongsToMany, no need for a model representing that pivot table.
I assume your models are Desk and User:
// Desk model
public function users()
{
return $this->belongsToMany('User', 'desk_user_list', 'deskId', 'userId');
}
// User model
public function desks()
{
return $this->belongsToMany('Desk', 'desk_user_list', 'userId', 'deskId');
}
Then:
$desks = Desk::with('users')->get(); // collection of desks with related users
foreach ($desks as $desk)
{
$desk->users; // collection of users for particular desk
}
// or for single desk with id 5
$desk = Desk::with('users')->find(5);
$desk->users; // collection of users
$desk->users->first(); // single User model

Resources