Laravel : how to get the list of element by the parent's parent - laravel

I have 3 layers of model relationships
the Grandparent Class
class GrandParent extends Model
{
protected $guarded = [];
public function parents()
{
return $this->hasMany('App\Parent');
}
public function childs()
{
return $this->hasManyThrough('App\Childs', 'App\Parent');
}
}
the parent Class
class Parent extends Model
{
public function grandParent() {
return $this->belongsTo('App\GrandParent', 'grandParent_id', 'id');
}
public function child()
{
return $this->hasMany('App\Child');
}
}
The child class
class Child extends Model
{
public function parent() {
return $this->belongsTo('App\Parent', 'parent_id', 'id');
}
}
i want to get list of Child by the grandParent ID
There is any way to get the list by simple Query
i am using laravel 5.5
thanks.

You need to add the grandparent_id and user_id from the user_table like below.
public function childs()
{
return $this->hasManyThrough('App\Childs', 'App\Parent','grandparent_id','parent_id','id','id');
}
In your Controller file.
$data = Grandparent::find($grandparent_id)->childs;

Related

laravel relationship between 5 tables

I have 5 tables User, Profile, Address,State,City .Need to create relationship between tables.Address has State id , City id and Profile id in the table.Profile has User Id in the table.City has State Id in the table. How to write relationship between table
class City extends Model
{
public function state() {
return $this->belongsTo('App\State');
}
public function addresses() {
return $this->hasMany('App\Address');
}
}
class State extends Model
{
public function cities() {
return $this->hasMany('App\City');
}
public function addresses() {
return $this->hasMany('App\Address');
}
}
class Profile extends Model
{
public function address() {
return $this->belongsTo('App\Address');
}
public function user() {
return $this->belongsTo('App\User');
}
}
class Address extends Model
{
public function profile() {
return $this->belongsTo('App\Profile');
}
public function city() {
return $this->belongsTo('App\City');
}
public function state() {
return $this->belongsTo('App\State');
}
}
// users table
public function profile(){
return $this->hasOne('App\Profile');
}
Generally your model design is true, i have edited a few parts. Try the codes below.
class City extends Model
{
public function state()
{
return $this->belongsTo('App\State');
}
public function addresses()
{
return $this->hasMany('App\Address');
}
}
class State extends Model
{
public function cities()
{
return $this->hasMany('App\City');
}
public function addresses()
{
return $this->hasMany('App\Address');
}
}
class Profile extends Model
{
public function addresses()
{
return $this->hasMany('App\Address');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
class Address extends Model
{
public function profile()
{
return $this->belongsTo('App\Profile');
}
public function city()
{
return $this->belongsTo('App\City');
}
public function state()
{
return $this->belongsTo('App\State');
}
}
class User extends Model
{
public function profile()
{
return $this->hasOne('App\Profile');
}
}
By the way, Laravel relationships add default keys according to your method names. If you have problem about it you can find info from official documents. For example:
$this->belongsTo('App\Model', 'foreign_key', 'other_key');
as #mustafa.akcoban says...
When you use belongsTo Eloquent will work as follow
$this->belongsTo('App\City', 'foreign_key', 'other_key');
// foreign_key = is the primary key in the related model, by default 'id' for Eloquent
// other_key = is the field in the current model that contains the id of the other model, by default othermodelname_id for Eloquent
// For eg. 'App\City', 'id', 'city_id'
When you use hasMany Eloquent works as follow
$this->hasMany('App\Model', 'currentmodel_id', 'primary_key');
// currentmodel_id = is the field that contains the current model primary key in the related model
// primary_key = is the current primary key model that will be in the other model, by default id for Eloquent
// For eg. 'App\City', 'state_id', 'id'
Remember you can or can't use second and third parameter, if something is wrong Laravel dump will tell you what column was not found in the table, and you will can fix.
Please try and practice this, and let me know how it works :)

How in laravel to make a deep HasManyThrough?

I created a relationship like this:
Type.City.Street.House.Apartment
In this relation, the apartment must depend on the House and on the Type at the same time, so result sql query must be like this:
select * from `apartments` where `apartments`.`house_id` in ('1', '2', '3') and `type_id` = '777'
The problem is that the HasManyThrough relationship only looks at a two of levels and it's not possible to get to the very first model with it.
Please, advise how this can be done?
My models definations:
class Type extends Model {
public function city() {
return $this->hasMany('App\City');
}
}
class City extends Model {
public function street() {
return $this->hasMany('App\Street');
}
}
class Street extends Model {
public function house() {
return $this->hasMany('App\House');
}
}
class House extends Model {
public function Apartment() {
return $this->hasMany('App\Apartment');
//->where('type_id', '=' type.id) ?????
}
}
class Apartment extends Model {
public $fillable = ['house_id', 'type_id']
}
I would add a mapping for house_id in Apartment model and sets bidirectional mappings among your models
class Apartment extends Model {
public $fillable = ['house_id', 'type_id'];
public function house() {
return $this->belongsTo('App\House', 'house_id');
}
}
class Type extends Model {
public function city() {
return $this->hasMany('App\City');
}
}
class City extends Model {
public function type() {
return $this->belongsTo('App\Type', 'type_id');
}
public function street() {
return $this->hasMany('App\Street');
}
}
class Street extends Model {
public function city() {
return $this->belongsTo('App\City', 'city_id');
}
public function house() {
return $this->hasMany('App\House');
}
}
class House extends Model {
public function street() {
return $this->belongsTo('App\Street', 'street_id');
}
public function Apartment() {
return $this->hasMany('App\Apartment');
//->where('type_id', '=' type.id) ?????
}
}
then you can query apartments as per your criteria like
Apartments::whereHas('house.street.city.type', function ($query) use ($type_id) {
$query->where('id', '=', $type_id);
})
->whereHas('house', function ($query) use ($house_ids) {
$query->whereIn('id', $house_ids);
});
And i guess there is no need for type_id in Apartments model
I created a HasManyThrough relationship with unlimited levels: Repository on GitHub
After the installation, you can use it like this:
class Type extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function Apartment() {
return $this->hasManyDeep(Apartment::class, [City::class, Street::class, House::class])
->where('apartments.type_id', $this->id);
}
}
Unfortunately, this doesn't work with eager loading.

how can I show this combination with select?

models structure it looks like the following
class Attribute extends Model
{
public function products()
{
return $this->belongsToMany(Product::class);
}
public function attribute_options()
{
return $this->hasMany(AttributeOption::class);
}
}
class AttributeOption extends Model
{
public function attribute_option()
{
return $this->hasMany(CombinationDetail::class);
}
public function attribute(){
return $this->belongsTo(Attribute::class);
}
}
class Combination extends Model
{
public function combination_details()
{
return $this->hasMany(CombinationDetail::class);
}
}
class CombinationDetail extends Model
{
protected $fillable = ['attribute_options_id'];
public function attribute_options()
{
return $this->belongsTo(AttributeOption::class);
}
}
Relationship models like this.
combination table
combination_details table
how can i show this with selectbox or div with javascript

Laravel 5 Polymorphic Relations Touch Parent Timestamp

I have the following models with polymorphic relationship
class Sector extends Model {
public function image() {
return $this->morphOne('App\Models\Image', 'imageable');
}
}
class Image extends Model {
protected $touches = ['imageable'];
public function imageable() {
return $this->morphTo();
}
}
I want to touch the parent (Sector) model's timestamps when updating the image of the sector. I have added the $touches variable on Image model.
But this is not working.
See if this works.
class Sector extends Model {
public function image() {
return $this->morphOne('App\Models\Image', 'imageable');
}
}
class Image extends Model {
protected $touches = ['sector'];
public function imageable() {
return $this->morphTo();
}
public function sector() {
return $this->morphedByMany('App\Models\Sector', 'imageable');
}
}

Laravel 5, How to get a collection of 2nd generation of children?

If I have the Grandparent, how do I get a single collection of its' parents' children?
Grandparent
`Class Grandparent extends Model
{
public function parents()
{
return $this->hasMany('\App\Parent');
}
}`
Parent
`Class Parent extends Model
{
public function grandparent()
{
return $this->belongsTo('\App\Grandparent');
}
public function children()
{
return $this->hasMany('\App\Child');
}
}`
Child
`Class Child extends Model
{
public function parent()
{
return $this->belongsTo('\App\Parent');
}
}`
A Collection of Collections could also work.

Resources