Laravel 5.3 relationship issue - php

class Game extends Model
{
public function regions() {
return $this->hasMany('Region');
}
public function servers() {
return $this->hasMany('Server');
}
}
class Region extends Model
{
public function servers() {
return $this->belongsToMany('Server');
}
}
class Server extends Model
{
public function regions() {
return $this->hasMany('Region');
}
}
Every game has a server and every server has a region.
I'm trying to get all the games, its server and its region:game=Game::with('regions', 'regions.servers')->find($id);
I get an error, that: Base table or view not found: 1146 Table 'region_server' doesn't exist (SQL: select servers.*, region_server.region_id as pivot_region_id, region_server.server_id as pivot_server_id from servers inner join region_server on servers.id = region_server.server_id where region_server.region_id in (4, 5)
What am I doing wrong?
Thanks!

Your relationships seems to be broken, you should do it like this:
class Game extends Model
{
public function regions() {
return $this->hasMany('Region');
}
public function servers() {
return $this->hasMany('Server');
}
}
class Region extends Model
{
public function servers() {
return $this->hasMany('Server');
}
}
class Server extends Model
{
public function region() {
return $this->belongsTo('Region');
}
}
According to the above relationships,
Every Game has many Servers.
Every Server belongs to a Region
Every Region has many Servers
Hope this helps

Related

Laravel hasManyThrough polymorphic table not working

I've following relationship:
class Project extends Model
{
public function invitors()
{
return $this->hasMany(Invitation::class)
}
}
// User model
class User extends Model
{
public function invitations()
{
return $this->morphMany('App\Invitation', 'invitee');
}
}
// Business Model
class Business extends Model
{
public function invitations()
{
return $this->morphMany('App\Invitation', 'invitee');
}
}
// Invitation model
class Invitation extends Model
{
public function invitee()
{
return $this->morphTo();
}
public function project()
{
return $this->belongsTo(Project::class);
}
}
What I want is to get project invitors (users, and businesses). When I use from $project->invitors->invitee its not working.
In your example $project->invitors is a collection of Invitation instances, and it hasn't property invitee. You can use helper pluck to loop $project->invitors and get their invitees:
$invitees = $project->invitors->pluck('invitee');
As a response to the first comment:
to get specific attributes of fetched linked models ("invitee") you can specify accessors:
class Business extends Model
{
...
public function getInviteeNameAttribute() {
return $this->name;
}
}
class User extends Model
{
...
public function getInviteeNameAttribute() {
return $this->first_name . ' ' . $this->last_name;
}
}
...then get that attribute from invitee:
$invitees[0]->invitee_name
See https://laravel.com/docs/7.x/eloquent-mutators#defining-an-accessor

Laravel Polymorphic Relations returns NULL

I've read many posts about this issue but none of them works for me. I have a 'ISA' relationship in my database. A person can be either a Patient or a Nurse:
class Person extends Model
{
protected $table = 'persons';
public function commentable()
{
return $this->morphTo();
}
}
class Patient extends Model
{
public function persons()
{
return $this->morphMany('App\Person', 'commentable');
}
}
class Nurse extends Model
{
public function persons()
{
return $this->morphMany('App\Person', 'commentable');
}
}
This is my tables and the data inside them:
And this is my Route:
Route::get('person', function () {
$person = Person::find(1)->commentable();
return json_decode(json_encode($person), true);
});
I get an empty array!
You have to access the relationship as a property:
$person = Person::find(1)->commentable;

Laravel Eloquent model JOIN a MAX record

I'm new to Laravel and I'd like to know how to use eloquent model to join a max(date) record...
App\SchemasGroup::find(7)->schemas()->get()->max('schemasVersion')->get();
I find a group of schemas (schemas_groups table) based on ID, then get the schemas from that group (schemas table), and I want to join the 'date' and 'version' field from schemas_versions table with the last version (so, max date or version field) ...
Relations are defined as:
class SchemasGroup extends Model
{
public function schemas() { return $this->hasMany('App\Schema'); }
}
class Schema extends Model
{
public function group() { return $this->belongsTo('App\SchemasGroup'); }
public function versions() { return $this->hasMany('App\SchemasVersion'); }
}
class SchemasVersion extends Model
{
public function schema() { return $this->belongsTo('App\Schema'); }
public function updatedBy() { return $this->belongsTo('App\User','updated_by'); }
}
Getting the user name who updated that last version would also be lovely...
Apparently it was easy with defining chaining models.
class Schema extends Model
{
public function group() { return $this->belongsTo('App\SchemasGroup'); }
public function versions() { return $this->hasMany('App\SchemasVersion'); }
public function latestVersion() { return $this->hasOne('App\SchemasVersion')->latest(); }
}
and then fetching the data with:
App\SchemasGroup::with('schemas.latestVersion.updatedBy')->find($schemaGroupId);

Eloquent model relationship for intermediate table

Consider the following table structure:
user table
id
name
lang_region_id
lang_region table
id
lang_id
region_id
lang table
id
name
region table
id
name
Fairly new to the Laravel framework, but trying to setup Eloquent models and relationships to an existing database. I want to establish the relationship between my user model and the lang and region models. The lang_region table defines what language and region combinations are available and then we can link each user to a valid combination.
I have read through the Laravel documentation several times looking for the proper relationship type, but is seems that the Many to Many and Has Many Through relationships are close, but since our user.id isn't used in the intermediate table I may be out of luck.
Sorry for the amateur question, but just getting used to Laravel and ORMs in general.
I would use the lang_region table as both a pivot table and a regular table with its own model.
class LangRegion extends model
{
protected $table = 'lang_region';
public function language()
{
return $this->belongsTo(Language::class, 'lang_id');
}
public function region()
{
return $this->belongsTo(Region::class);
}
public function users()
{
return $this->hasMany(User::class);
}
}
class User extends model
{
protected $table = 'user';
public function langRegion()
{
return $this->belongsTo(LangRegion::class);
}
}
class Language extends model
{
protected $table = 'lang';
public function regions()
{
$this->belongsToMany(Region::class, 'lang_region', 'lang_id', 'region_id');
}
public function users()
{
$this->hasManyThrough(User::class, LangRegion::class, 'lang_id', 'lang_region_id');
}
}
class Region extends model
{
protected $table = 'region';
public function languages()
{
$this->belongsToMany(Language::class, 'lang_region', 'region_id', 'lang_id');
}
public function users()
{
$this->hasManyThrough(User::class, LangRegion::class, 'region_id', 'lang_region_id');
}
}
If I understand what you want correctly:
class User extends Model {
private function lang_region() {
return $this->hasOne(LangRegion::class)
}
public function lang() {
return $this->lang_region()->lang();
}
public function region() {
return $this->lang_region()->region();
}
}
class LangRegion extends Model {
public function lang() {
return $this->belongsTo(Lang::class);
}
public function region() {
return $this->belongsTo(Region::class);
}
}

Retrieving relationships of relationships using Eloquent in Laravel

I have a database with the following tables and relationships:
Advert 1-1 Car m-1 Model m-1 Brand
If I want to retrieve an Advert, I can simply use:
Advert::find(1);
If I want the details of the car, I could use:
Advert::find(1)->with('Car');
However, if I also want the detail of the Model (following the relationship with Car), what would the syntax be, the following doesn't work:
Advert::find(1)->with('Car')->with('Model');
Many thanks
It's in the official documentation under "Eager Loading"
Multiple relationships:
$books = Book::with('author', 'publisher')->get();
Nested relationships:
$books = Book::with('author.contacts')->get();
So for you:
Advert::with('Car.Model')->find(1);
First you need to create your relations,
<?php
class Advert extends Eloquent {
public function car()
{
return $this->belongsTo('Car');
}
}
class Car extends Eloquent {
public function model()
{
return $this->belongsTo('Model');
}
}
class Model extends Eloquent {
public function brand()
{
return $this->belongsTo('Brand');
}
public function cars()
{
return $this->hasMany('Car');
}
}
class Brand extends Eloquent {
public function models()
{
return $this->hasMany('Model');
}
}
Then you just have to access this way:
echo Advert::find(1)->car->model->brand->name;
But your table fields shoud be, because Laravel guess them that way:
id (for all tables)
car_id
model_id
brand_id
Or you'll have to specify them in the relationship.
Suppose you have 3 models region,city,hotels and to get all hotels with city and region then
Define relationship in them as follows:-
Hotel.php
class Hotel extends Model {
public function cities(){
return $this->hasMany(City::class);
}
public function city(){
return $this->belongsTo('App\City','city_id');
}
}
City.php
class City extends Model {
public function hotels(){
return $this->hasMany(Hotel::class);
}
public function regions(){
return $this->belongsTo('App\Region','region_id');
}
}
Region.php
class Region extends Model
{
public function cities(){
return $this->hasMany('App\City');
}
public function country(){
return $this->belongsTo('App\Country','country_id');
}
}
HotelController.php
public function getAllHotels(){
// get all hotes with city and region
$hotels = Hotel::with('city.regions')->get()->toArray();
}
will adding the relation function just ask for the relation needed
public function Car()
{
return $this->belongsTo(Car::class, 'car_id')->with('Model');
}
but if you want a nested relation just use the period in the with
Advert::with('Car.Model')->find(1);
but for multi-relation use the array
Advert::with('Car','Model')->find(1);

Categories