accessing data from a pivot table in laravel - php

I am having trouble accessing data from an extra column in a pivot table.
I have two models (which are part of a larger application for managing grades in a k-12 school) - Grado and Subject. Grado refers to the grade, i.e first grade, second grade, etc. I want the administrator to be able to associate subjects to a grade level in a given year.
The mysql pivot table grado_subject contains:
id_grado_subject
year_grado_subject //year - column I want to access
grados_id_grados //foreign key id of grado
subjects_id_subjects //foreign key id of subject
created_at
updated_at
The Grado model:
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class Grado extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $table = 'grados';
protected $primaryKey = "id_grados";
protected $fillable = array('name_grados');
public static $rules = array(
);
public function subject()
{
return $this->belongsToMany('Subject','grado_subject','grados_id_grados','subjects_id_subjects')
->withPivot('year_grado_subject')
->withTimestamps();
}
public function groups()
{
return $this->hasMany('Group','id_grados','grados_id_grados');
}
}
The Subject Model:
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class Subject extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $table = 'subjects';
protected $primaryKey = "id_subjects";
protected $fillable = array('engSpanExtra_subjects', 'name_subjects','IntGrade_subjects');
public static $rules = array(
'name_subjects' => 'required',
'engSpanExtra_subjects' => 'required',
'IntGrade_subjects'=> 'required'
);
public function grado()
{
return $this->belongsToMany('Grado','grado_subject','subjects_id_subjects','grados_id_grados')
->withPivot('year_grado_subject')
->withTimestamps();
}
public function teacher()
{
return $this->belongsToMany('Teacher','subject_teacher','subjects_id_subjects','teachers_id_teachers');
}
}
In the GradoController:
class GradoController extends \BaseController {
public function index()
{
$grados = Grado::find(1);
$years = $grados->pivot->year_grado_subject;// line I get error on
return $years;
$grados->toarray();
return View::make('grados.index',compact('grados', 'years'));
}
When I try to retrieve all the years associated with a grade_subject I get the error: Trying to get property of a non-object.
Any help would be greatly appreciated!

public function subject()
{
return $this>belongsToMany('Subject','grado_subject','grados_id_grados','subjects_id_subjects')
->withPivot('year_grado_subject')
->withTimestamps();
}
You have some syntax errors I'm seeing in the above. First you have $this>belongsToMany which should be $this->belongsToMany
Another thing you might check is $this->belongsToMany('Subject', ...) You aren't including your Student model in a use clause therefore you have to use a fully qualified reference and it should be $this->belongsToMany('\Student', ...).
You have the same syntax errors in your Grado model. Check these first and see if your error is solved.

The pivot attribute is generated by the belongsToMany relationship, therefore it exists on the objects loaded by that relationship (subjects), not the primary object (grado).
For example:
// primary object is grado
$grado = Grado::find(1);
// loop through related subjects
foreach($grado->subject as $subject) {
// pivot attribute exists on related subject
echo $subject->pivot->year_grado_subject;
}
Or, if you were going the inverse way:
// primary object is subject
$subject = Subject::find(1);
// loop through related grados
foreach($subject->grado as $grado) {
// pivot attribute exists on related grado
echo $grado->pivot->year_grado_subject;
}

Related

Eloquent many-to-many returning an empty value

Good day. I am trying to convert some of my models to use Eloquent mechanisms from table joins. I have three tables, and I want to use one of them as a pivot table. The three tables are shown below
First table (cp_cases_counsel)
Followed by (cp_counsel)
Then,(cases_sc)
I am trying to implement a many-to-many relationship between cases_sc and cp_counsel using cp_cases_counsel as the pivot table.
These are my models
use App\Models\SupremeCases;
use Illuminate\Database\Eloquent\Model;
use App\Models\CounselCase;
class Counsel extends Model
{
//
protected $fillable = [];
protected $table = 'cp_counsel';
protected $connection = 'mysql2';
public function supreme()
{
return $this->belongsToMany(SupremeCases::class,'cp_cases_counsel','counsel_id','suitno');
}
}
For the Cases Model
use Illuminate\Database\Eloquent\Model;
use App\Models\Counsel;
class SupremeCases extends Model
{
//
protected $connection = "mysql2";
protected $fillable = [];
protected $table = 'cases_sc';
public $timestamps = false;
public function counsels()
{
return $this->belongsToMany(Counsel::class,'cp_cases_counsel','counsel_id','suitno');
}
}
Getting the counsels and their cases using
$counsels = Counsel::with('supreme')->get();
I get an empty result for the supreme node in the response as shown below
Please, what I'm I doing wrong?

Inserting a new row on Laravel using "save" method

I am studying Laravel and trying to insert a new row in my table estabelecimentos.
Why is this working to insert a new row:
$estabelecimento = Estabelecimento::create([
'nome' => $nome
]);
And this is not working? Using var_dump on save method it returns null.
$estabelecimento = new Estabelecimento();
$estabelecimento->nome = $nome;
$estabelecimento->save;
I already tried using try/catch but it doesn't throw errors, it just don't insert the row and returns null on save method.
My Class:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Estabelecimento extends Model
{
public $timestamps = false;
protected $fillable = ['nome'];
public function Comentarios()
{
return $this->hasMany(Comentario::Class);
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comentario extends Model
{
public $timestamps = false;
protected $fillable = ['nome', 'votes'];
public function Estabelecimento()
{
return $this->BelongsTo(Estabelecimento::Class);
}
}
Table estabelecimentos
name
type
extra
id
bigint(20)
PK - AUTOINCREMENT
nome
varchar(100)
-
save is a method and hence you call it with ().
so, replace the following line of code:
$estabelecimento->save;
with the following:
$estabelecimento->save(); // focus on `()`
Remember to always look at the documentation: https://laravel.com/docs/8.x/eloquent-relationships#the-save-method

Eloquent laravel : Get JSON representation of entry in table with all his relations

Model Ov.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Ov extends Model
{
protected $table = 'ov';
public $timestamps = true;
protected $fillable = array('version', 'macAddress');
protected $hidden = array('timestamps');
public function masters()
{
return $this->hasMany('App\Models\MasterEquipment', 'id_ov_foreign_key');
}
}
Model MasterEquipment.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class MasterEquipment extends Model
{
protected $table = 'masterEquipment';
public $timestamps = true;
protected $fillable = array('macAddress');
public function slaveEquipments()
{
return $this->hasMany('App\Models\SlaveEquipment', 'id_masterEquipment_foreign_key');
}
public function equipment()
{
return $this->hasOne('App\Models\Equipment', 'id_masterEquipment_foreign_key');
}
}
I would like to retrieve the entire JSON representation for a given version of OV:
I tried :
return Ov::where('version', '3')->with('masters')->get();
But it doesn't work, I only get the following JSON: (with masters empty)
{
"version": 3,
"macAddress": "00:01:02:04:04",
"masters":[]
}
Could you help me please ?
You need to use Eloquent Resources for that.
It's pretty simple. Instead of returning your model you will return your resource and pass your model into the resource collection as follows:
return new OvCollection(Ov::where('version', '3')->with('masters')->get());
You have to create your resource collection first of course.
Your relation builder is wrong.
From your model i conclude that your two tables are like this
ov table
------------------------------
id | version | macAddress
------------------------------
masterEquipment table
---------------------
id | macAddress
---------------------
Only thing that is relating both table is macAddress
So your modal relation should be like this
Ov modal
public function masters()
{
return $this->hasMany(MasterEquipment:class, 'macAddress','macAddress);
}
Then only this will work
return Ov::where('version', '3')->with('masters')->get();

Laravel One-to-One relationship not working

I have 2 database tables => mobile_phones , mobile_users
Schema for mobile_phones
phone_id (primary key , auto_increment)
phone_name (varchar(150))
phone_model (int (11))
Schema for mobile_users
user_id (primary key , auto_increment)
username (varchar(150))
mobile_phone_id (foreign key referencing mobile_phones(phone_id))
Model class for mobile_phones
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class MobilePhone extends Model
{
protected $primaryKey = "phone_id";
public $timestamps = false;
protected $table = "mobile_phones";
protected $fillable = array("phone_name","phone_model");
public function mobileUser()
{
return $this->hasOne("MobileUser","mobile_phone_id");
}
}
Model class for mobile_users
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class MobileUser extends Model
{
protected $primaryKey = "user_id";
public $timestamps = false;
protected $table = "mobile_users";
protected $fillable = array("username","mobile_phone_id");
public function mobilePhone()
{
return $this->belongsTo("MobilePhone","phone_id");
}
}
I am trying to establish One-to-One relationship between MobileUser and MobilePhone models but it isn't happening. Below is my code in Controller's action -
public function query()
{
$getUsername = MobilePhone::find(1)->username;
echo $getUsername;
}
The above code gives me NULL when I do a var_dump()
I did check similar questions on SO and they used with() (but this isn't necessary). I am referring Laravel 5.2 docs and they state that we can access relate record in another relation using Eloquent's dynamic properties. Link to that docs is here
Please Help !!
You need to call the function of your model so do the following
public function query()
{
$getUsername = MobilePhone::find(1)->mobileusers;
echo $getUsername->username;
}
When doing this:
public function query()
{
$getUsername = MobilePhone::find(1)->username;
echo $getUsername;
}
You try to access a username property out of a MobilePhone number, which is incorrect.
Try this:
public function query()
{
$getUsername = MobilePhone::find(1)->mobileUser->username;
echo $getUsername;
}
Also I encourage you to use the with statement as it will preload all dependencies needed (means 1 single query) instead of eager loading it (many queries)
Something like this :
public function query()
{
$getUsername = MobilePhone::find(1)->mobileUser;
echo $getUsername->username;
}

laravel insert a new row that has a key from another table and a null columns

This is my restaurant table:
the restaurant table has a adminID field . and this is the admin table:
I have a form that has the values of both the restaurant and the admin,
This is Admin model:
class Admin extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
public function restaurant(){
return $this->belongsTo('Restaurant', 'ID');
}
This is Restaurant model:
class Restaurant extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
public function admin(){
return $this->hasOne('Admin', 'adminID');
}
This is the RestaurantsController for storing a new restaurant
$input = Input::all();
$validation = Validator::make($input, Admin::$rules);
if($validation->passes()){
$validation = Validator::make($input, Restaurant::$rules);
if ($validation->passes())
{
$admin = Admin::create(Input::only('username', 'password', 'mobileNumber', 'firstName', 'lastName'));
as you see now I have the $admin variable,
My Question
what is the statmnet that I need to insert a new restaurant
please note that I can take the adminID from $admin->id
please note that the restaurant has a null columns like logo and addressManualID
At first, you don't need to implement UserInterface and RemindableInterface and and also don't use use UserTrait, RemindableTraitto create all of your models but only the User model if you have a User model for user authentication (log in/out). If the Admin model is being used as a replacement of the User model then you need to implement those interfaces and also need to use those traits as well. Also you need to explicitly declare the protected $table property to assign the table name which is being used for Admin model (If you are not using User model) and also you need to change some settings in app/config/auth.php file as given below:
'model' => 'Admin',
'table' => 'admins', // Could be anything else, same as protected $table property
Then try following to save the the related model when creating Admin:
//...
if ($validation->passes()) {
$admin = Admin::create( Input::only('username', ...) );
$restaurent = new Restaurant(Input::only(...));
$admin->restaurant()->save($restaurent);
}
You will want to use associate() method.
$restaurant = Restaurant::find(10);
$restaurant->admin()->associate($admin);
$restaurant->save();
Reference: http://laravel.com/docs/eloquent#inserting-related-models

Categories