Laravel Relationships recursive - php

I have 3 Models:
City:
protected $fillable = [
'name', 'latitude', 'longitude', 'code', 'country_id', 'status', 'weather_code',
];
public function translations() {
return $this->hasMany('App\Models\CityTranslation');
}
public function country() {
return $this->hasMany('App\Models\Country');
}
CityTranslation
protected $fillable = [
'name', 'lang', 'city_id',
];
public function city() {
return $this->hasOne('App\Models\City', 'id', 'city_id');
}
and Country
protected $fillable = [
'code', 'latitude', 'longitude', 'currency_id', 'timezone', 'dam_date', 'status',
];
public function city() {
return $this->hasMany('App\Models\City');
}
My problem is when a go through my CityTranslations and display the city name for the selected language i want also to show information about the city and its country.
There is no problem to call $cityTranslation->city->longitude, but when i call $cityTranslation->city->country->code it gives me a MySQL error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'countries.city_id' in 'where clause' (SQL: select * from `countries` where `countries`.`city_id` = 4439 and `countries`.`city_id` is not null)
How can I make recursive relations?

Try
$cityTranslation = \App\CityTranslation::with('city.country')->get();
Thats if you want to get all city Translation and it related city and country. The you can loop through and get the country code.
if you want to pick only one city Translation and it related item you can do
$cityTranslation = \App\CityTranslation::with('city.country')->find($id);
Change this (in your city model)
public function country() {
return $this->hasMany('App\Models\Country');
}
to
public function country() {
return $this->belongsTo('App\Models\Country');
}
Because country can have many cities and every city must belong to a country

Related

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 Column not found: 1054 Unknown column 'created_at' in 'order clause'

I have defined to not use timestamps, but still laravel forces to use timestaps... Im using laravel 5.6.
When I visit page for example - http://mypage/api/videos/21/comments
I get an error - "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'created_at' in 'order clause' (SQL: select * from videos_comments where videos_comments.video_id = ▶"
app/Providers/VideoComment.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class VideoComment extends Model
{
protected $table = 'videos_comments';
public $timestamps = false;
protected $fillable = [
'text', 'userid', 'date'
];
public function videos() {
return $this->belongsTo('App\Video', 'id', 'video_id');
}
public function member() {
return $this->belongsTo('App\Member', 'userid', 'member_id');
}
}
app/Providers/Video.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
class Video extends Model
{
protected $table = 'videos';
public $timestamps = false;
use Sluggable;
public function sluggable() {
return [
'slug' => [
'source' => 'title'
]
];
}
public function comments() {
return $this->hasMany('App\VideoComment', 'video_id', 'id');
}
public function member() {
return $this->belongsTo('App\Member', 'userid', 'member_id');
}
}
VideoCommentController.php function
public function index(Video $video) {
return response()->json($video->comments()->with('member')->latest()->get());
}
If you use latest() in your query then you have to add created_at in your db table, read more.
The latest and oldest methods allow you to easily order results by date. By default, the result will be ordered by the created_at column.
You can easily use orderBy and first() instead of latest() when you haven't created_at column.

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');
}

column not found: 1054 Unknown column in laravel eloquent relationships

I'm trying to count number of schedules on a homecourt on current timestamp, now I have tried hasManyThrough in laravel between homecourt, userhomecourt, schedule but got this error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'timeFrom' in 'where clause' (SQL: select count(*) as aggregate from `tblHomeCourts` where `homeCourtId` = 1 and `timeFrom` <= 1496207469 and `timeTo` > 1496207469)
I have these relationship in HomeCourt model
public function playerCount()
{
return $this->hasManyThrough(Schedule::class,UserHomeCourt::class,'homeCourtId','userHomeCourtId','homeCourtId');
}
where am I wrong here? please correct it out.
class HomeCourt extends Model
{
protected $table = 'tblHomeCourts';
protected $primaryKey = 'homeCourtId';
protected $appends = ['homeCourtProfilePicUrl'];
public static $snakeAttributes = false;
protected $fillable = [
'homeCourtName',
'cityId',
'homeCourtProfilePic',
'gameType',
'courtType',
'numberOfCourts',
'lights',
'membershipStatus',
'dayCost',
'address',
'lat',
'long',
'userId',
'homeCourtStatus',
];
protected $hidden = ['homeCourtProfilePic', 'created_at', 'updated_at', 'homeCourtStatus', 'userId', 'cityId'];
public function getHomeCourtProfilePicUrlAttribute()
{
return ($this->attributes['homeCourtProfilePic'] != "" || $this->attributes['homeCourtProfilePic'] != null) ? Constant::HOMECOURT_PROFILE_URL . $this->attributes['homeCourtProfilePic'] : null;
}
/*relation for there now*/
public function user()
{
return $this->belongsTo(User::class, 'homeCourtId', 'homeCourtId');
}
/*player count*/
public function playerCount()
{
return $this->hasManyThrough(Schedule::class,UserHomeCourt::class,'homeCourtId','userHomeCourtId','homeCourtId');
}
}

Querying one-to-one in laravel

I have two models city and business.I have to perform below queries
Find Business by city name.
Find Top 10 cities which have the maximum business.
Here is the models
Business
class Business extends \Eloquent
{
protected $fillable = [
'business_type',
'first_name',
'last_name',
'email',
'password',
'designation_id',
'name',
'description',
'portfolio_id',
'image',
'city_id',
'package_id',
'group_tag_id'
];
public function city()
{
return $this->belongsTo('City');
}
}
City
class City extends \Eloquent
{
protected $fillable = ['name', 'district_id'];
public function business()
{
return $this->hasMany('Business');
}
}
So How can i do this?
Hi You can fetch this by this ways :
Find Top 10 cities which have the maximum business:
$city = City::with('business')->get()->sortBy(function($query) {
return $query->business->count();
}, SORT_REGULAR, true)
->take(10);
Find Business by city name.
Business::whereHas('city', function ($q) {
$q->where('name', 'like', 'search_string');//name is the city_name as per your attributes name
})->get();

Categories