laravel belongsTo not working with one to one relation - php

i have two tables:
**plans:**
planId, plan_name
**Users:**
userId, user_name, password, planId
i tried to get the name of the plan where i select all users.
this is the users model:
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Users extends Authenticatable {
public $timestamps = false;
protected $table = 'users';
protected $primaryKey = 'userId';
protected $fillable = [
'user_name',
'password',
];
protected $hidden = [
'_token',
];
public function plan()
{
return $this->belongsTo('App\Plans', 'planId');
}
public function validateCredentials( MyUserInterface $user, array $credentials ) {
$plain = $credentials["password"] . $user->getAuthPasswordSalt();
return $this->hasher->check( $plain, $user->getAuthPassword() );
}
}
and this is the plan model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Plans extends Model {
public $timestamps = false;
protected $table = 'plans';
protected $primaryKey = 'planId';
protected $fillable = [
'plan_name'
];
protected $hidden = [
'_token',
];
public function users()
{
return $this->hasMany('App\Users', 'planId');
}
}
when i used:
\App\Users::get();
there is no relations in the output... there is only the users.
what can i do?
i tried to used hasOne and the same issue...
tnx a lot

You can eager load the relationships like this:
\App\Users::with('plan')->get();
Or add a $with property to always eager load it when you fetch an user:
class Users extends Authenticatable
{
protected $with = [
'plan'
];
}
If you don't want to eager load it, you can access the plan of each user's instance like this:
$users = \App\Users::get();
foreach ($users as $user) {
dd($user->plan);
}

Related

Laravel eloquent relationship for finding multilevel array

I am a beginner in laravel i want to create a nested api in which one model is connected with another using hasmany relationship here it is:
Model 1:
class Project extends Model
{
use HasFactory;
protected $table = 'projects';
public $timestamps = true;
protected $fillable = [
'title','description'
];
function categorywithqestions()
{
return $this->hasMany('App\Models\questionmd','cat','id');
}
}
Model 2:
class questionmd extends Model
{
use HasFactory;
protected $table = 'questions';
public $timestamps = true;
protected $fillable = [
'title',
'description',
'cat',
'q_type',
];
function relatedquestions()
{
return $this->hasMany('App\Models\relatedquestion','question_id','id');
}
}
Model 3:
class relatedquestion extends Model
{
use HasFactory;
protected $table = 'related_questions';
public $timestamps = true;
protected $fillable = [
'question_id',
'title',
'description',
];
}
and here is controller:
$callback = function($query) {
$query->where('q_type', '=', 'direct_ask');
};
$questionmd = Project::whereHas('categorywithqestions', $callback)
->with(['categorywithqestions' => $callback])->get();
return response()->json(['message' => 'Success', 'status' => 200,'data'=>$questionmd]);
I want to fetch the related questions also inside the "categorywithqestions" how to do it?
From what i see, you can use hasManyThrough helper.
The database structure should be like this.
1 Project hasMany categories
1 Category hasMany questions
projects
id - integer
name - string
categories
id - integer
project_id - integer
name - string
questions
id - integer
category_id- integer
commit_hash - string
on Project model you can do like this
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
/**
* Get all of the deployments for the project.
*/
public function deployments()
{
return $this->hasManyThrough(Deployment::class, Environment::class);
}
}
later on in you queries you can make
$questions = Project::all()->load('questions');
Please try this way.
$questionmd = Project::whereHas('categorywithqestions', function($q) {
$q->where('q_type', '=', 'direct_ask');
})->with(['categorywithqestions.relatedquestions'])->get();

how to get the propert of object that collect data from two tables and update column?

I want to update the ResidentID in the Room table. Where ResidentID is a foreign key refrence from Group Table. it is working well when I update ResidentId =2 manually, but I want to send the Group id to the ResidentID from the $allot_apps object.
public function View_GroupStudent()
{
$caps = Rooms::selectRaw('count(id) as c')->count();
$allot_apps = AllotmentApps::join('Groups','Groups.id','AllotmentApps.grpID')-
>orderBy('Groups.Group_CGPA', 'Desc')->get()->groupBy(
function($item) {
return $item->grpID;
}
)->take($caps);
$merits=Rooms::all()->toArray();
foreach ($merits as $key) {
$merits=Rooms::where('id',$key)->Update(['ResidentID'=>'2']);
}
return view('admin.ViewGroups', compact('allot_apps'));
}
$allot_apps
$allt-apps variables
$merit
AllotmentApps Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class AllotmentApps extends Model
{
//
protected $fillable = [
'sname', 'fname', 'Roll_No','cnic','domicile','cgpa','Department','Session','degreeProgram','contactNo','GcontactNo','preAddress','permAddress','fee','challanNo','app_status','fee_status','grpID',
];
protected $primaryKey = 'id';
protected $table = 'AllotmentApps';
public function groups()
{
return $this->belongsTo('App\Groups');
}
}
Groups Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Groups extends Model
{
//
protected $fillable = ['Group_CGPA',];
protected $primaryKey = 'id';
public function allotmentApps()
{
return $this->hasMany('App\AllotmentApps');
}
}
Room Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Rooms extends Model
protected $fillable = ['id','HostelID','ResidentID'];
protected $primaryKey = 'id';
{
public function hostels()
{
return $this->belongsTo('App\Hostels');
}
}

How in Laravel 7 resources show only some fields of a creator?

In my Laravel 7.6 app I use resource collection with creator retrieved
and I want in some cases show not all creator fields, but only some of them. I have in my control:
$activeVotes = Vote
::getByStatus('A')
->where('votes.id', 1)
->with('voteCategory')
->with('creator')
return (new VoteCollection($activeVotes));
In app/Http/Resources/VoteCollection.php I have :
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class VoteCollection extends ResourceCollection
{
public static $wrap = 'votes';
public function toArray($request)
{
$this->collection->transform(function ($votes) {
return new VoteResource($votes);
});
return parent::toArray($request);
}
}
and in app/Http/Resources/VoteResource.php :
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class VoteResource extends JsonResource
{
public static $wrap = 'votes';
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'creator' => $this->whenLoaded('creator'),
...
How to defined if I need to show only some fields of creator above ?
EDITED:
My app/User.php has :
<?php
namespace App;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use DB;
...
class User extends Authenticatable implements MustVerifyEmail
{
use Billable;
use HasApiTokens, Notifiable;
use funcsTrait;
protected $table = 'users';
protected $primaryKey = 'id';
public $timestamps = false;
protected $userAvatarPropsArray = [];
protected $avatar_filename_max_length = 255;
protected $full_photo_filename_max_length = 255;
protected static $password_length = 8;
protected $fillable = [ 'username', 'email', 'status', 'provider_name', 'template_id', 'provider_id', 'first_name', 'last_name', 'phone', 'website', 'password',
'activated_at', 'avatar', 'full_photo', 'updated_at', 'verified' ];
protected $hidden = [ 'password', 'remember_token' ];
...
public function votes()
{
return $this->hasMany('App\Vote', 'creator_id', 'id');
}
...
and app/Vote.php :
<?php
namespace App;
use DB;
use App\MyAppModel;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use App\Http\Traits\funcsTrait;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Validation\Rule;
class Vote extends MyAppModel
{
use funcsTrait;
use Sluggable;
use HasTags;
protected $table = 'votes';
protected $primaryKey = 'id';
public $timestamps = false;
protected $casts = [
'meta_keywords' => 'array'
];
protected $fillable = ['name', 'slug', 'description', 'creator_id', 'vote_category_id', 'is_quiz', 'status', 'image'];
protected static $logAttributes = ['*'];
...
public function creator(){
return $this->belongsTo('App\User', 'creator_id','id');
}
In Vote and user models there are referenced to other model.
Otherwize
->with('creator')
does not work.
Are there some options I missed?
Thanks!
I think you have two options.
Use hidden on your user model
By using hidden, see the Laravel docs, you specify which fields are shown in the JSON or Arrray representation of your model.
Select the fields in your with statement
$activeVotes = Vote::getByStatus('A')->where('votes.id', 1)
->with('voteCategory')
->with(['creator' => function ($query) {
$query->select('id', 'first_name');
}]);
return (new VoteCollection($activeVotes));
Your need to include the field id, as this is responsible to join these two.

laravel belongsTo on User Model not working

Following are my relations in laravel , I am unable to access company using User's Object, but i am getting null when i try to access it, please see my code below to get the picture
following are my models
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Zizaco\Entrust\Traits\EntrustUserTrait;
use Session;
use Illuminate\Support\Facades\DB;
class User extends Authenticatable
{
use Notifiable;
use EntrustUserTrait;
protected $table = 'tbl_users';
protected $primaryKey = 'id';
protected $guarded = ['id'];
const API = 'api';
const WEB = 'web';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'last_login', 'Address', 'Age', 'DateOfBirth', 'created_by', 'deleted_by'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'is_admin' => 'boolean',
];
public function isAdmin()
{
return $this->is_admin;
}
static function GetUserNamebyID($id)
{
$name = User::select("name")->where(["id" => $id])->pluck('name');
if (isset($name[0])) {
return $name[0];
} else {
return '';
}
}
public function loginlogout()
{
$this->hasMany("App\Models\LoginLogoutLogs", 'userID');
}
public function company()
{
$this->hasMany("App\Models\Company", "company_id");
}
}
And following is my companies Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use DB;
use App\Models\CarePlanData;
use Session;
class Company extends Model
{
protected $table = 'companies';
protected $primaryKey = 'id';
protected $guarded = ['id'];
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'phone_no', 'address', 'password', 'description', 'city', 'company_logo', 'country', 'email'
];
static public function fetchAllActiveCompanies()
{
return DB::table("companies")->where(['is_active' => 1])->pluck('name', 'id');
}
// change company to hasmany
public function users()
{
return $this->hasmany('App\Models\User');
}
}
and this is how i am trying to access the Company , but i am getting null.
public function fetchCompany(){
$User = User::find($user->id);
dd($User->company());
}
First of all if a user belongs to 1 company then it should be:
public function company()
{
$this->belongsTo("App\Models\Company", "company_id");
}
then fetchCompany() should be
public function fetchCompany(){
$User = User::with('company')->find($user->id);
dd($User->company);
}
You need to use with to load the relations. You pass the name of the function which defines the relation in your User model to with like this with('function_name').
Your actual question is:
You have belongTo Relation between User and Company but when you trying to access the Company via user object, you get null
In your User.php Model put the following function but if you already have then leave it:
public function company()
{
$this->belongsTo("App\Models\Company", "company_id");
}
Then
Replace this function:
public function fetchCompany(){
$User = User::find($user->id);
dd($User->company());
}
To is one:
public function fetchCompany(){
$User = User::find($user->id);
if($User){
dd($User->company()->get());
}
}
or to this one:
public function fetchCompany(){
$User = User::find($user->id);
if($User){
dd($User->company);
}
}
actually if your company_id field is on user model, then your relation should be
public function company()
{
$this->belongsTo("App\Models\Company", "company_id");
}
unless a user can have many companies ?

Laravel MongoDB hasMany relationship is not working

I'm try to create a relationship between albums and photos (an Album has many photos). Below is my controller and what my models look like. Interesting enough, the reverse relationship photo->album (belongsTo) works fine! but the album->photos returns an empty collection.
## The hasMany relationship does NOT work... I get an empty collection
<?php
class AlbumController extends BaseController
{
public function show(Request $request, $album_id)
{
$album = Album::find($album_id);
dd($album->photos);
}
}
## Results:
# Collection {#418
# items: []
# }
## The belgonsTo relationship works
<?php
class PhotoController extends BaseController
{
public function show(Request $request, $photo_id)
{
$photo = Photo::find($photo_id);
dd($photo->album);
}
}
<?php
namespace App;
use DB;
use Jenssegers\Mongodb\Eloquent\SoftDeletes;
use Moloquent;
class Album extends Moloquent
{
use RecordActivity, SoftDeletes;
protected $connection = 'mongodb';
protected $table = 'albums';
protected $collection = 'albums';
protected $primaryKey = "_id";
protected $dates = ['deleted_at'];
protected $fillable = ['user_id','name','is_private'];
public function photos()
{
// Neither seems to work
//return $this->embedsMany('Photo');
return $this->hasMany('App\Photo');
}
}
<?php
namespace App;
use DB;
use Jenssegers\Mongodb\Eloquent\SoftDeletes;
use Moloquent;
class Photo extends Moloquent
{
use RecordActivity, SoftDeletes;
protected $connection = 'mongodb';
protected $table = 'photos';
protected $collection = 'photos';
protected $primaryKey = "_id";
protected $dates = ['deleted_at'];
protected $fillable = ['album_id', 'user_id', 'name', 'folder', 'is_private', 'caption'];
protected $hidden = [];
// user and album belongsTo works
public function user()
{
return $this->belongsTo('App\User');
}
public function album()
{
return $this->belongsTo('App\Album');
}
}
The issue had to do with the fact that my IDs were ObjectID and it seems to be an issue with Jessengers Laravel MongoDB Drivers... we have actually decided to move back to MariaDB to fully utilize Eloquent/Relationships
I did the same thing as yours and i found that nothing wrong with Mongodb. Because Mongodb defined the "_id" as primary key and that's the reason it couldn't get the correct relationship: belongsTo and hasMany. So i did a small change by declared the $primaryKey = "id" on the top of parent Model and it worked fine
this worked for me.
/**
* #return HasMany
*/
public function tasks(): HasMany
{
return $this->hasMany(ProjectTask::class, 'project_id', 'idAsString');
}

Categories