laravel relationship between 3 tables - many-to-many - php

I have 3 tables (Models)
Advertise :
id
title
...
Value:
id
title
amount
....
Field:
id
name
title
...
and my pivot tables is like:
advertise_id
value_id
field_id
how can I set relations in my models and do a crud(please give me an example)?
all the relations are many to many

3 model classes accordingly:
class Advertise extends Model
{
public function fields()
{
return $this->belongsToMany(Field::class);
}
public function values()
{
return $this->belongsToMany(Value::class);
}
}
class Field extends Model
{
public function advertises()
{
return $this->belongsToMany(Advertise::class);
}
public function values()
{
return $this->belongsToMany(Value::class);
}
}
class Value extends Model
{
public function fields()
{
return $this->belongsToMany(Field::class);
}
public function advertises()
{
return $this->belongsToMany(Advertise::class);
}
}

Related

Laravel, four model relationship

I have four models: Animal(which can only be "dog" or "cat"), Category, Breed and Post.
Table data:
Animal:
- id
- name
Category:
- id
- name
- animal_id
Breed:
- id
- name
- category_id
Post:
- id
- breed_id
What I need is to get all Posts that are about dogs. Have any ideas?
Update:
My models:
class Animal extends Model
{
public function categories()
{
return $this->hasMany(Category::class)->orderBy('name', 'ASC');
}
}
class Category extends Model
{
public function animal()
{
return $this->belongsTo(Animal::class);
}
public function breeds()
{
$this->hasMany(Breed::class)->orderBy('name', 'ASC');
}
}
class Breed extends Model
{
public function category()
{
return $this->belongsTo(Category::class);
}
public function posts()
{
return $this->hasMany(Posts::class);
}
}
class Posts extends Model
{
public function breed()
{
return $this->belongsTo(Breed::class);
}
}
First of all you need to properly set up the relations in the eloquent models,
here is an example of code,
For Post Eloquent Model
And post must have the column animal_id
public function animal(){
return $this->belongsTo(Animal::class);
}
Then you have to query like
$posts = Post::whereHas('animal',function($q){
return $q->where('name','dog');});
After that you will get the posts which belongs to animal data where animal name is dog. And if you want to query with your current database structure that is not recommended because of complex and long query.

Laravel Relationship tables passing extra "s" with id name

I am getting "'lessons.subjects_id" while there is "subject_id" in lesson table. dont know where is problem in my relationship. My relationship models are as under:
class Lessons extends Model
{
public function subject()
{
return $this->belongsTo('Lea\Subjects');
}
public function category()
{
return $this->belongsTo('Lea\Category');
}
}
Subject Model is:
class Subjects extends Model
{
public function category()
{
return $this->belongsTo('Lea\Category');
}
public function Lessons()
{
return $this->hasMany('Lea\Lessons');
}
}
If you didn't respect the Laravel convention you have to teach him about yours ;) by adding you foreign key name.
In the documentation you have :
Eloquent determines the foreign key of the relationship based on the
model name. In this case, the Phone model is automatically assumed to
have a user_id foreign key. If you wish to override this convention,
you may pass a second argument to the hasOne method:
class Lessons extends Model
{
public function subject()
{
// your foreign key
return $this->belongsTo('Lea\Subjects', 'subject_id');
}
public function category()
{
return $this->belongsTo('Lea\Category');
}
}
And
class Subjects extends Model
{
public function category()
{
return $this->belongsTo('Lea\Category');
}
public function Lessons()
{
// your foreign key
return $this->hasMany('Lea\Lessons', 'subject_id');
}
}

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