Get associated properties - php

I need to fetch some data from associated tables, but I can't deal with it. I have the following tables with functions.
Class User
{
public function lastGoals()
{
return $this->hasMany('App\UserGoals')->last()->with('data');
}
}
Class UserGoals
{
protected $fillable = [
'user_id', 'goal_id'
];
public function data()
{
return $this->hasOne('App\CreatorGoals', 'id', 'goal_id');
}
public function goalsBelong()
{
return $this->belongsTo('App\CreatorGoals', 'goal_id', 'id');
}
}
Class CreatorGoals
{
protected $fillable = [
'id', 'label', 'type'
];
public function scopeFront($query)
{
return $query->select('id', 'label', 'type')->where('is_front', 1);
}
}
I need to fetch all UserGoals with UserID and it's labels,
For now I have:
$data = User::user(Auth::guard('web')->user()->id)->with('lastGoals')->first();
I have a collection of users but I don't know to fetch the label of each user goal. I have tried:
$data->lastGoals->data->label;
$data->lastGoals->label;
$data->data->lastGoals->label;
But I still have errors. How can I fetch the label of each user goal?

Related

Laravel find() does not get data from the DB

I have a resource Controller with this index method like this:
public function index()
{
$args = [];
$args = array_merge($args, $this->data_creator(35, 12, 'book'));
$args = array_merge($args, $this->data_creator(37, 12, 'kit'));
$args = array_merge($args, $this->data_creator(38, 12, 'game'));
$args['menu_links'] = [
'books' => route('shopping-products.category', Category::find(25)->slug),
'videos' => route('shopping-products.category', Category::find(24)->slug),
'kits' => route('shopping-products.category', Category::find(23)->slug),
'games' => route('shopping-products.category', Category::find(22)->slug),
];
return view('frontend.shop.products.index', $args);
}
But it returns this error:
Trying to get property 'slug' of non-object
And when I dd(Category::find(25), Category::find(24), Category::find(23), Category::find(22)); I get NULL results.
Meaning that it can not find data with specified ids.
However there are 25 records stored at the categories table:
So what is going wrong here? How can I fix this issue?
I would really appreciate any idea or suggestion from you guys...
Thanks in advance.
Here is Category.php Model:
class Category extends Model
{
use Sluggable, SoftDeletes;
protected $table = 'categories';
protected $primaryKey = 'cat_id';
protected $guarded = [];
/**
* Return the sluggable configuration array for this model.
*
* #return array
*/
public function sluggable()
{
return [
'slug' => [
'source' => 'cat_name'
]
];
}
public function path()
{
return "/products/categories/$this->slug";
}
public function children()
{
return $this->hasMany(Category::class, 'cat_parent_id', 'cat_id');
}
public function parents()
{
return $this->hasMany(Category::class, 'cat_id', 'cat_parent_id');
}
public function products()
{
return $this->belongsToMany(Product::class, 'category_products', 'ctp_cat_id', 'ctp_prd_id');
}
public function news()
{
return $this->belongsToMany(News::class, 'category_news', 'ctn_cat_id', 'ctn_nws_id');
}
public function galleries()
{
return $this->belongsToMany(Gallery::class, 'category_galleries', 'ctg_cat_id', 'ctg_gly_id');
}
public function uploaded()
{
return $this->hasMany(UploadedFile::class, 'upf_object_id', 'cat_id')->where('upf_object_type_id', '=', '107');
}
public function articles()
{
return $this->belongsToMany(Article::class, 'article_category', 'act_cat_id', 'act_art_id');
}
public function olympiadExam()
{
return $this->belongsToMany(OlympiadExam::class, 'olympiads_exams_categories', 'oec_ole_id', 'oec_cat_id');
}
public function olympiadExamQuestion()
{
return $this->belongsToMany(OlympiadExamQuestion::class, 'olympiads_exams_questions_categories', 'oes_cat_id', 'oes_oeq_id')->orderBy('oeq_number', 'asc');
}
public function attr_attributes()
{
return $this->hasMany(CategoryAttribute::class, 'category_id', 'cat_id');
} //
public function attr_product()
{
return $this->hasMany(Product::class, 'prd_cat_att_id', 'cat_id');
} //
public function couponRelation()
{
return $this->hasMany(couponRelation::class, 'object_id', 'cat_id')->where('object_type', 'product_category');
}
public function magazines()
{
return $this->belongsToMany(Magazine::class, 'category_magazine', 'category_id', 'magazine_id');
}
}
And when I do: dd(Category::where('cat_id', 25), Category::where('cat_id', 24), Category::where('cat_id', 23), Category::where('cat_id', 22)); I get this as result:
The problem is because you are using SoftDeletes so soft deleted models will automatically be excluded from query results. In your case, look like Category with id 22, 23, 24, 25 are soft deleted. To get it, you need to use withTrashed() as mentioned in the doc. For example:
Category::withTrashed()->find(22)->slug
per an answer above: if you are using soft deletes you need to add
Category::withTrashed()
However, you can wrap the command in an optional() helper function.
optional(Category::find(22))->slug
// if you are using soft delete
optional( Category::withTrashed()->find(22) )->slug
this will return null if 22 does not exist instead of throwing an exception error.

Is there a way to get a nested Eloquent model based on ids from another table?

Hey there stackoverflow
I am currently building a course application as part of my laravel project.
My problem lies in how the eloquent handle model relations, i'm still kinda new to eloquent, so hopefully you can answer my question.
The structure
The Course has many episodes and each episode has many sections.
Which means I have 3 tables in the DB. Courses -> course_episodes -> course_episode_sections
ID table is where i connect courses with users - course_users.
Right now i can create courses and and put in all the data correctly.
The Problem
I need to retrieve all the courses and its nested children that the user has bought, which is connected in the course_users table with columns course_id and user_id
Course structure
Same stucture in DB
course: {
name: null,
sub_title: null,
estimate: null,
trailer: null,
type: null,
text: null,
course_episodes: [
{
name: null,
section: [
{
order: null,
type: null,
content: null,
},
]
},
]
}
Model Pictures
My models as of right now.
class CourseUsers extends Model {
protected $fillable = [
'id',
'course_id',
'user_id',
'active',
];
protected $hidden = [
'deleted_at',
'updated_at',
'deleted_at'
];
public function courses()
{
return $this->belongsToMany(Course::class);
}
public function user(){
return $this->belongsTo(User::class);
}
public function scopeFindForUserId($query, $userId)
{
return $query->where(function ($q) use ($userId) {
$q->where(function ($q) use ($userId) {
$q->where('user_id', $userId);
});
});
}
Course model
class Course extends Model{
protected $fillable = [
'id',
'name',
'sub_title',
'type',
'estimate',
'trailer',
'gateway_id',
'text',
'active',
];
protected $hidden = [
'deleted_at',
'updated_at',
'deleted_at'
];
public function courseEpisode()
{
return $this->hasMany(CourseEpisode::class);
}
public function courseUsers() {
return $this->hasMany(CourseUsers::class);
}
public function scopeActive(Builder $builder)
{
return $builder->where('active', true);
}
Course episode Model
class CourseEpisode extends Model implements HasMedia {
use HasMediaTrait;
protected $fillable = [
'id',
'course_id',
'order',
'name',
];
protected $hidden = [
'deleted_at',
'updated_at',
'deleted_at'
];
public function course()
{
return $this->belongsTo(Course::class);
}
public function courseSection()
{
return $this->hasMany(CourseEpisodeSection::class);
}
Course episode sections
class CourseEpisodeSection extends Model {
protected $fillable = [
'id',
'course_episode_id',
'order',
'type',
'content'
];
protected $hidden = [
'deleted_at',
'updated_at',
'deleted_at'
];
public function courseEpisode()
{
return $this->belongsTo(CourseEpisode::class);
}
According to your explanation, course_users table holds many-to-many relationship between Course and User model. In case of a many-to-many relationship, you actually don't need a CourseUser model. This kind of table which holds many-to-many relationship is called pivot table. Read more from the Official Documentation
I am defining only the relationships with your Course, User, CourseEpisode, CourseEpisodeSection models.
Course.php
class Course extends Model
{
public function courseEpisodes()
{
return $this->hasMany(CourseEpisode::class);
}
public function users()
{
return $this->belongsToMany(User::class,'course_users')->withPivot('active');
}
}
CourseEpisode.php
class CourseEpisode extends Model
{
public function courseSections()
{
return $this->hasMany(CourseSection::class);
}
}
User.php
class User
{
public function courses()
{
return $this->belongsToMany(Course::class,'course_users')->withPivot('active');
}
}
If you want to get all the children relationships from a user, use nested eager loading :
$user_with_nested_course_data = User::with('courses.courseEpisodes.courseSections')->find($id);

Laravel Eloquent method updateOrCreate exceeds execution time when updating

So the problem is that when I try to update my entity it finds it updates it but gets stuck in a loop probably and doesn't exit. When I check the database, even before the 60 seconds of execution time that I have expires, the values that I have changed are updated.
If i constantly refresh (and here is where it gets crazy) the updated at values for other lectures starts to change every second while it executes this loop.
When creating (not finding the id on the condition It creates it without a problem)
I have Lectures which looks like this:
class Lecture extends Model
{
use Searchable;
use SoftDeletes;
protected $primaryKey = 'id';
protected $touches = ['themes', 'educationTypes', 'subjects'];
protected $fillable= [
'name', 'description', 'user_id', 'field_id', 'approved'
];
public static function boot()
{
parent::boot();
static::saved(function ($model) {
$model->themes->filter(function ($item) {
return $item->shouldBeSearchable();
})->searchable();
});
}
public function user(){
return $this->belongsTo('App\User')->with('companies');
}
public function geographies(){
return $this->belongsToMany('App\Geography');
}
public function educationTypes(){
return $this->belongsToMany('App\EducationType', 'lecture_education_type')->withTimestamps();;
}
public function themes(){
return $this->belongsToMany('App\Theme','lecture_theme', 'lecture_id', 'theme_id')->withTimestamps();;
}
public function subjects(){
return $this->belongsToMany('App\Subject', 'lecture_subject')->withTimestamps();;
}
public function cases(){
return $this->belongsToMany(
'App\CompanyCase' ,
'case_company_lecture',
'lecture_id',
'case_id',
'id',
'id')->withTimestamps();
}
public function companies(){
return $this->belongsToMany(
'App\Company' ,
'case_company_lecture',
'lecture_id',
'company_id',
'id',
'id'
);
}
public function field(){
return $this->belongsTo('App\Field');
}
public function toSearchableArray()
{
$this->themes;
$this->user;
$this->educationTypes;
$this->subjects;
$this->geography;
return $this->toArray();
}
}
This is the controller:
public function storeLecture(Request $request) {
$lecture_id = $request->get('lecture_id');
// It gets stuck between the comments
$lecture = Lecture::updateOrCreate(['id' => $lecture_id],
[
'name'=> request('name'),
'description'=> request('description'),
'user_id'=> request('user_id')]
);
// and doesn't update the themes, edu types subjects and etc.
$company_id = $request->get('company_id');
$company = Company::find(request('company_id'));
$lecture->companies()->sync([$company->id]);
$eduTypes= $request->get('education_types');
$themes= $request->get('themes');
$subjects = $request->get('subjects');
$geographies = $request->get('geographies');
$lecture->themes()->sync($themes);
$lecture->educationTypes()->sync($eduTypes);
$lecture->subjects()->sync($subjects);
$lecture->geographies()->sync($geographies);
$n1 = new Notification();
$n1->send(request('user_id'), 1, 'new_lecture', $lecture->id);
$user = User::where('id', $request->id)->first();
$user_with_companies = $user->load('companies');
$slug = $user_with_companies->companies->first()->slug;
return response(['success' => true]);
}
This is the frontend method sending the request (in between I have a middleware checking if the user is admin (possible to create a lecture) based on the this.selectedExpert.id, which doesn't interfere).
createUpdateLecture() {
const url = `${window.location.origin}/lecture/create/${
this.selectedExpert.id
}`;
this.$http
.post(url, {
education_types: this.allEducationTypes
.filter(el => el.checked)
.map(a => a.id),
themes: this.allThemes.filter(el => el.checked).map(a => a.id),
geographies: this.allGeographies
.filter(el => el.checked)
.map(a => a.id),
subjects: this.allSubjects.filter(el => el.checked).map(a => a.id),
name: this.lecture.name,
description: this.lecture.description,
user_id: this.selectedExpert.id,
company_id: this.company.id,
lecture_id: this.lecture.id
})
.then(res => {
console.log(res);
this.$parent.showLectureCreateModal = false;
// window.location.reload();
});
}
As I can see what is happening I probably use the method really badly but I just want to understand it better for further usage.
After a few days of researching and testing it turns out that it is not the updateOrCreate method causing the problem because I tried with two different functions for creating and updating and the update function was still having the same problem.
The problem is created from Algolia which is used for searching based on different fields in the platform. Fx. in Themes
class Theme extends Model
{
use SoftDeletes;
use Searchable;
protected $touches = ['lectures'];
public function lectures(){
return $this->belongsToMany('App\Lecture');
}
public function toSearchableArray()
{
$this->lectures;
return $this->toArray();
}
}
Removing the searchable from the models did the trick!

Eloquent: Two foreign keys in a table pointing to the same table

I have two models:
Team
Game (Played between two games)
The Game model has two foreign keys pointing to the Team model - team1_id & team2_id.
Here's the code for Team model:
class Team extends Eloquent
{
protected $table = 'team';
protected $fillable = [
'name',
'color',
'year'
];
public function games()
{
return $this->hasMany(\App\Models\Game::class);
}
}
Code for Game model:
class Game extends Eloquent
{
protected $table = 'game';
protected $casts = [
'team1_id' => 'int',
'team2_id' => 'int'
];
protected $fillable = [
'team1_id',
'team2_id',
'location',
'start_at'
];
public function team1()
{
return $this->hasOne(\App\Models\Team::class, 'team1_id');
}
public function team2()
{
return $this->hasOne(\App\Models\Team::class, 'team2_id');
}
}
I get an error saying the column could not be found.
return $this->hasMany(\App\Models\Game::class, 'team1_id');
This works, but the problem is that I want to get games depending on both team1_id and team2_id.
You had to specify the foreign key and the local key you use to reference that relation
public function localTeam()
{
return $this->belongsTo(\App\Models\Team::class, 'id', 'team1_id');
}
public function foreignTeam()
{
return $this->belongsTo(\App\Models\Team::class, 'id', 'team2_id');
}

Laravel retrieve values from foreign key

I have these models with their related db tables,at the moment I can retrieve all the requirement
Requirement::all()
but I just have a list of foreigns key (destination_id,applier_id,doc_id). How can i retrieve directly the row connected to that foreigns key?
class Requirement extends Model
{
protected $fillable = [
'required',
'destination_id',
'applier_id',
'doc_id'
];
public function destination()
{
return $this->belongsTo(Destination::class);
}
public function applier()
{
return $this->belongsTo(Applier::class);
}
public function doc()
{
return $this->belongsTo(Doc::class);
}
}
class Doc extends Model
{
protected $fillable = [
'type',
'description',
'note'
];
public function requirements()
{
return $this->hasMany(Requirement::class);
}
}
class Destination extends Model
{
protected $fillable = [
'country',
'passying_country',
'transfer_conditions',
'passing_conditions'
];
public function requirements()
{
return $this->hasMany(Requirement::class);
}
}
You can call with() function instead of all(). So if you try this following :
$requirements = Requirement::with('destination', 'applier', 'doc')->get();
Make it dd($requirements) and look the output.
Hope it will work.

Categories