Laravel multiple relation return null value - php

Code:
$user = User::with('role.modules.subModule.module.moduleGroup')
->where('id', Auth::id())
->first();
return $user->role->modules->first()->sub_module;
user collection is like this:
Why can't I access with this statment?
return $user->role->modules->first()->sub_module;
User Model:
public function role()
{
return $this->hasOne(Roles::class, 'id', 'role_id');
}
Roles Model:
public function modules()
{
return $this->hasMany(RoleModules::class, 'role_id', 'id');
}

I solved the problem:
$user = User::with('role.modules.subModule.module.moduleGroup')
->where('id', Auth::id())
->first();
$user = collect($user);
$modules = collect();
for ($i = 0; $i < count($user['role']['modules']); $i++) {
if ($user['role']['modules'][$i]['sub_module'] != null)
$modules->push([
'module_group_name' => $user['role']['modules'][$i]['sub_module']['module']['module_group']['title'],
'module_group_must' => $user['role']['modules'][$i]['sub_module']['module']['module_group']['must'],
'module_name' => $user['role']['modules'][$i]['sub_module']['module']['name'],
'module_must' => $user['role']['modules'][$i]['sub_module']['module']['must'],
'module_ico' => $user['role']['modules'][$i]['sub_module']['module']['ico'],
'sub_module_name' => $user['role']['modules'][$i]['sub_module']['sub_name'],
'sub_module_must' => $user['role']['modules'][$i]['sub_module']['must'],
'sub_module_link' => $user['role']['modules'][$i]['sub_module']['link'],
]);
}
return $modules;

Related

Laravel: query a model with count

how can query in laravel with model method ?
i have a counter method in city model and i want to use this in my select query in response
how can i write this ?
my City model
public function mobile()
{
return $this->hasMany(Mobile::class);
}
public function mobile_count()
{
return $this->mobile()->count();
}
my query
public function findCityWithID($id)
{
$subgroup = City::select('id', 'name', 'state_id')->where('state_id', $id)->orderBy('name')->get();
return response()->json($subgroup);
}
i want have in $subgroup each City mobile counts
The Model:
public function mobiles()
{
return $this->hasMany(Mobile::class);
}
The Query:
$cities = City::withCount('mobiles')->where('state_id', $id)->get();
$response[];
foreach ($cities as $city) {
response[
'id' => $city->id;
'name' => $city->state;
'state_id' => $city->state_id;
'mobile_count' => $city->mobile_count;
];
}
return response()->json($response);

Property [id] does not exist on the Eloquent builder instance in Laravel 8 and Livewire 2.7

My users can create multiple usercar's when selecting from a database of car's. I need to grab the selected car values, but when I dd the values, I get a Property [id] does not exist on the Eloquent builder instance. error. wire:model="car_id" is the select input value used in the code below.
AddUserCar.php
...
class AddUserCar extends Component
{
public $showAnotherModel = false;
// Steps
public $totalSteps = 8;
public $step = 1;
// User
public $super;
public $first_name;
public $last_name;
public $email;
public $status = 1;
public $role = 'Driver';
// Usercar
public $car_id;
public $calc_date;
public $year;
public $model;
// Form Function
public $car_year;
//public $cars;
//public $modelId;
...
public function moveAhead()
{
if($this->step == 1) {
$newCar = Car::where('id', '=', $this->car_id)->get();
dd($newCar->id); // This is where I get error
$this->usercarCreated = Usercar::create([
'year' => $newCar->start_year,
'model' => $newCar->model,
'car_id' => $this->car_id,
'user_id' => Auth::user()->id,
'tenant_id' => Auth::user()->tenant_id,
'calc_date' => now()->format('m-d-Y'),
]);
$this->resetErrorBag();
$this->resetValidation();
}
...
public function render()
{
return view('livewire.add-user-car',
['pageTitle' => 'Add Driver Car']);
}
}
Use ->get() to retrieving all rows from a table :
$cars = Car::where('id', '=', $this->car_id)->get();
foreach($cars as $car){
echo $car->id;
}
// ERROR, because $cars isn't a single row
dd($cars->id);
Use ->first() to retrieving a single row / column from a table.
$car = Car::where('id', '=', $this->car_id)->first();
// or
$car = Car::find($this->car_id);
// WORK
dd($car->id);
$newCar = Car::where('id', '=', $this->car_id)->get();
This statement does not find any data, so $newcar is empty, and an empty object has no ID

How to get global user profile data available in all blade views?

I have user with user profile data stored in database and I am able to read that data on user profile page. What I want is to be able to fetch that data (variable is $profile) on any view in my application. What is the best way to do that? Any help is appreciated. Here is my code.
UserProfileController.php
<?php
namespace App\Http\Controllers;
use App\User;
use App\UserProfile;
use Illuminate\Support\Facades\Auth;
class UserProfileController extends Controller
{
/**
* Display the specified resource.
*
* #param \App\Property $property
* #return \Illuminate\Http\Response
*/
public function show($name)
{
$viewer = User::find(Auth::user()->id);
$owner = User::where('name', $name)->first();
// Check if user with given username exists
if($viewer->id !== $owner->id)
{
return abort(404);
}
if(!$profileId = User::getIdFromName($name)){
return abort(404);
}
$profile = UserProfile::profileDetails($profileId, $viewer->id);
//dd($profile);
return view('profile.show', compact('profile'));
}
}
UserProfile.php
<?php
namespace App;
use App\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Model;
class UserProfile extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public static function profileData($profileId, $viewerId)
{
$user = User::find($viewerId);
$profile = DB::table('users as u')
->select(DB::raw("
data.*,
u.id, u.gender_id, u.name, u.email, u.age, u.premium
"))
->leftJoin('user_profiles as data', 'data.user_id', '=', 'u.id')
->where('u.id', $profileId)
->first();
return $profile;
}
public static function profileDetails($profileId, $viewerId)
{
$profile = static::profileData($profileId, $viewerId);
if ($profile) {
if ($viewerId != $profileId) {
# Viewer is displaying another user's profile.
$myProfile = false;
} else {
$myProfile = true;
}
}
# Populate profile data array
$profile = [
'viewerId' => $viewerId,
'profile_id' => $profileId,
'myProfile' => $myProfile,
'status' => Value::fieldLabel('status', $profile->status),
'first_name' => $profile->first_name,
'last_name' => $profile->last_name,
'job' => $profile->job,
'distance' => $profile->distance,
'city' => $profile->city,
'interested_in' => Value::fieldLabel('interested_in', $profile->interested_in),
'age_from_preference' => $profile->age_from_preference,
'age_to_preference' => $profile->age_to_preference,
'looking_for' => Value::fieldLabel('looking_for', $profile->looking_for),
'personal_quote' => $profile->personal_quote,
'bio_about' => $profile->bio_about,
'postal_code' => $profile->postal_code,
'country' => $profile->country,
'height' => $profile->height,
'orientation' => Value::fieldLabel('orientation', $profile->orientation),
'sexual_preferences' => Value::fieldLabel('sexual_preferences', $profile->sexual_preferences),
'body_type' => Value::fieldLabel('body_type', $profile->body_type),
'relationship_status' => Value::fieldLabel('relationship_status', $profile->relationship_status),
'children' => Value::fieldLabel('children', $profile->children),
'smoke' => Value::fieldLabel('smoke', $profile->smoke),
'education' => Value::fieldLabel('education', $profile->education),
'astro' => Value::fieldLabel('astro', $profile->astro),
'hobbies' => $profile->hobbies,
'workplace' => $profile->workplace,
'sports' => Value::fieldLabel('sports', $profile->sports),
'movies_series' => Value::fieldLabel('movies_series', $profile->movies_series),
'music' => Value::fieldLabel('music', $profile->music),
'food' => Value::fieldLabel('food', $profile->food),
'literature' => Value::fieldLabel('literature', $profile->literature),
'mobile_number' => $profile->mobile_number,
];
return $profile;
}
}
You can use View::share() method to share variable in all views.
Since you want to share authenticated user data it will be good to use middleware for that:
class SomeMiddleware {
public function handle($request, Closure $next) {
$viewer = User::find(Auth::user()->id);
$owner = User::where('name', $name)->first();
// Check if user with given username exists
if($viewer->id !== $owner->id) {
return abort(404);
}
if(!$profileId = User::getIdFromName($name)){
return abort(404);
}
$profile = UserProfile::profileDetails($profileId, $viewer->id);
View::share('profile_details', $profile);
}
/**
* You can get in view like this:
* {{ $profile_details }}
*/
}
** Method 2 **
In your AppServiceProvider You can use view()->composer(). For example:
...
public function boot(){
view()->composer('*', function ($view) {
if(!Auth::check()) {
abort(401);
}
$viewer = User::find(Auth::user()->id);
$owner = User::where('name', $name)->first();
// Check if user with given username exists
if($viewer->id !== $owner->id) {
return abort(404);
}
if(!$profileId = User::getIdFromName($name)){
return abort(404);
}
$profile = UserProfile::profileDetails($profileId, $viewer->id);
View::share('profile_details', $profile);
$view->with('profile_details', $profile);
});
}
...

Retrieving data from multiple tables

I have Student table in my database which connect many to many with Courses table , when I try to select student from the table ,give me error :
"Undefined property: stdClass::$courses (View: C:\xampp\htdocs\laravel\resources\views\admin\student\index.blade.php)
<td>
#foreach($student->courses as $course)
<label>{{$course->name_courses}}</label>
#endforeach
</td>
edit and update have error:
public function edit(Student $student)
{
$id = $student->id;
$students = DB::table('student')
->join('contacts', 'student.contact_id', '=', 'contacts.id')
->join('users', 'contacts.user_id', '=', 'users.id')
->select('contacts.*', 'users.*', 'student.*')
->where(['student.id' => $id])
->first();
$courses = Course::all();
$course2 = array();
foreach ($courses as $course) {
$course2[$course->id] = $course->name;
}
return view('admin.student.edit', ['student' => $students]);
}
function update:
public function update(Request $request, Student $student)
{
Student::updateStudent($request->all());
if (isset($request->courses)) {
$student->courses()->sync($request->courses);
} else {
$student->courses()->sync(array());
}
return redirect("/admin/student")->with('success','Has been Update');
}
in the model Student
public static function createStudent($data) {
/*
$user = User::create([
'username' => $data['user_name'],
'role_id' => 1,
'password' => Hash::make($data['password']),
]);*/
$user = User::createUser($data) ;
$data['user_id'] = $user['id'];
$contactId = Contact::createContact($data);
$student = Student::create([
'contact_id' => $contactId
]);
return $student;
}
public static function updateStudent($data) {
/* DB::table('users')
->where('id', $data['user_id'])
->update([
'username' => $data['username']
]);*/
User::updateUser($data);
Contact::updateContact($data);
}
public function courses()
{
return $this->belongsToMany('App\Course');
}
Could someone tell me what to do to fix this ?
Looks like you are using Route model binding, and your student is injected, if thats the case you don't need to use DB::table(...
public function edit(Student $student)
{
$courses = Course::all();
$course2 = array();
foreach ($courses as $course) {
$course2[$course->id] = $course->name;
}
return view('admin.student.edit', ['student' => $student]);
}
You have 2 problems in your code:
1-
The below indicates that you're using Query Builder instead of Eloquent
$students = DB::table('student')
->join('contacts', 'student.contact_id', '=', 'contacts.id')
->join('users', 'contacts.user_id', '=', 'users.id')
->select('contacts.*', 'users.*', 'student.*')
->where(['student.id' => $id])
->first();
And you didn't join the courses table.
2-
Query Builder will return Array, not an object. So to access the course you should do this instead, $course['name_courses']:
<td>
#foreach($student->courses as $course)
<label>{{$course['name_courses']}}</label>
#endforeach
</td>
To fix the issue, it's easier to do the following:
$students = Student::with('courses', 'contacts, 'contacts.users')
->where('id', '=', $id) //the 'id' here refers to 'student' ID.
->first();
and then you can loop over the courses that belong to this particular student.

Using 'with' in many-to-many relationship in Laravel

I have a table user - User(Model), which has relationship:
public function roles()
{
return $this->belongsToMany(Config::get('entrust.role'), Config::get('entrust.role_user_table'), 'user_id', 'role_id');
}
public function regions() {
return $this->belongsToMany('App\Regions', 'user_region', 'user_id', 'region_id');
}
I am trying this query, but it doesn't me the required result
$result = User::with(['roles' => function($query) {
$query->select('user_id','role_id');
},
'regions' => function($query) {
$query->select('user_id','region_id', 'region_name');
}])
->where('user_id', '=', $id)
->get()->toArray();
It only gives me data from user table and doesn't give the relationship data.
What am I missing out??
The notation you are using should be used for constraints. From your code it seems you don't actually need any contraints.
$result = User::with(['roles', 'regions'])
->where('user_id', '=', $id)
->first()->toArray();
The relationship you defined is only a belongsTo. You should probably use a hasMany relationship.
If you're using 5.1 try this:
$result = User::whereHas(['roles' => function($query) {
$query->lists('user_id','role_id');
},
'regions' => function($query) {
$query->lists('user_id','region_id','region_name');
}])
->where('user_id', '=', $id)
->all();
if not remove all() and use get()
This worked for me.
$users = User::with('regions', 'roles')->get();
$userInfo = [];
foreach ($users as $user)
{
$userInfo[] = [
'users' => $user,
'regions' => $user->regions->toArray(),
'roles' => $user->roles->toArray(),
];
}

Categories