Inserting a new row on Laravel using "save" method - php

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

Related

Getting incorrect 'id' using sqlite in laravel [duplicate]

I am trying to use email as my table's primary key, so my eloquent code is-
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserVerification extends Model
{
protected $table = 'user_verification';
protected $fillable = [
'email',
'verification_token'
];
//$timestamps = false;
protected $primaryKey = 'verification_token';
}
And my DB is like this-
but if I do this-
UserVerification::where('verification_token', $token)->first();
I am getting this-
{
"email": "sdfsdf#sdfsdf.sdf",
"verification_token": 0,
"created_at": "2016-01-03 22:27:44",
"updated_at": "2016-01-03 22:27:44"
}
So, the verification token/primary key becomes 0.
Can anyone please help?
This was added to the upgrade documentation on Dec 29, 2015, so if you upgraded before then you probably missed it.
When fetching any attribute from the model it checks if that column should be cast as an integer, string, etc.
By default, for auto-incrementing tables, the ID is assumed to be an integer in this method:
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L2790
So the solution is:
class UserVerification extends Model
{
// if your key name is not 'id'
// you can also set this to null if you don't have a primary key
protected $primaryKey = 'your_key_name';
public $incrementing = false;
// In Laravel 6.0+ make sure to also set $keyType
protected $keyType = 'string';
}
On the model set $incrementing to false
public $incrementing = false;
This will stop it from thinking it is an auto increment field.
Laravel Docs - Eloquent - Defining Models
Theres two properties on the model you need to set. The first $primaryKey to tell the model what column to expect the primary key on. The second $incrementing so it knows the primary key isn't a linear auto incrementing value.
class MyModel extends Model
{
protected $primaryKey = 'my_column';
public $incrementing = false;
}
For more info see the Primary Keys section in the documentation on Eloquent.
I was using Postman to test my Laravel API.
I received an error that stated
"SQLSTATE[42S22]: Column not found: 1054 Unknown column" because Laravel was trying to automatically create two columns "created_at" and "updated_at".
I had to enter public $timestamps = false; to my model. Then, I tested again with Postman and saw that an "id" = 0 variable was being created in my database.
I finally had to add public $incrementing false; to fix my API.
keep using the id
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserVerification extends Model
{
protected $table = 'user_verification';
protected $fillable = [
'id',
'email',
'verification_token'
];
//$timestamps = false;
protected $primaryKey = 'verification_token';
}
and get the email :
$usr = User::find($id);
$token = $usr->verification_token;
$email = UserVerification::find($token);

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

accessing data from a pivot table in laravel

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

Creating timestamps throws an error for model with dynamic table name set in constructor

I have an Eloquent model with constructor (below), that takes $type param. The types are - let's say - first, second or third.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model {
protected $table; // Define $table field
public function __construct($type = null, array $attributes = array()) {
// Initialize $table field
$this->table = isset($type) ? 'my_'.$type.'_table' : null;
parent::__construct($attributes);
}
?>
As you can see in the code above, I set the model's $table property to my_[type]_table, so I can use the model dynamically with one of 3 tables available. Like this:
// Somewhere in controller
$type = 'first';
$myModel = new MyModel($type);
$myModel->create(.....); // <= Error is thrown here
The problem is when Eloquent tries to create timestamps for the table, it doesn't care anymore about the table name I set in __construct() and it tries to create the timestamps for table called my_models (which is obviously based on the model's class name), instead of doing it for (in this case) my_first_table:
SQLSTATE[HY000]: General error: 1 no such table: my_models (SQL:
insert into "my_models" ("updated_at", "created_at") values
(2015-07-17 08:35:13, 2015-07-17 08:35:13))
Any way to keep the dynamic table name for the automatic timestamps creation? Im on Laravel 5.1.
When you call $myModel->create(), a new object is created and type is not passed to its constructor.
Just pass $type to $myModel->create() as one of the attributes, update the constructor:
public function __construct($attributes = array()) {
if (array_key_exists('type', $attributes)) {
$this->table = 'my_' . $attributes['type'] . '_model';
}
parent::__construct(array_except($attributes, 'type'));
}
and it should work.
a bit late
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model {
//-- using a mutator
public function setTypeAttribute($type)
{
//-- set type =)
$this->attributes['type'] = $type;
//-- then use this type for your table name convention
$this->setTable( 'my_'. $type .'_table' );
}
}
?>

Categories