Laravel8.x - Getting exception while accessing belongsTo relationship - laravel

I have a model class created in my laravel 8.x application with the code as given below
class City extends Model
{
use HasFactory;
protected $table = 'portal_cities';
public function belongsTo()
{
return $this->belongsTo(State::class); // also tried giving 'state_id' as second parameter
}
}
I have the portal_cities table as below
When i am trying to access the following code
$eventobj = App\Models\Event::find(1);
echo $eventobj->location->city->name;
It is giving the following error
Declaration of App\Models\City::belongsTo() should be compatible with Illuminate\Database\Eloquent\Model::belongsTo($related, $foreignKey = NULL, $ownerKey = NULL, $relation = NULL)
Can you please tell me what is causing the error and what can be done to rectify it?

change relation method name
for example:
public function state()
{
return $this->belongsTo(State::class); // also tried giving 'state_id' as second parameter
}

you can't create belongsTo() function as it is core function in model
so you need to change this
class City extends Model
{
use HasFactory;
protected $table = 'portal_cities';
public function state() // change this name
{
return $this->belongsTo(State::class);
}
}
you can check core function here
https://github.com/laravel/framework/blob/8.x/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php#L193

Related

Laravel exception: Creating default object from empty value

I'm getting this error just by instantiating a Model and setting a property.
$order_datail = new OrderDetail;
$order_detail->quantity = $product['quantity'];
I'm searching for hours for the cause of this problem but can't find it.
The constructor of OrderDetail is executed. table is order_details, but even by setting protected $table = 'order_details', I'm still getting this error. And yes there is a column 'quantity' in this table.
Strange thing is that I've no problem with other models.
$order = new Order;
$order->pickup_date = $request['date'];
$order->pickup_time = $request['pickupTime'];
The above code runs fine.
Model OrderDetail:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class OrderDetail extends Model
{
use SoftDeletes;
public function replaceds()
{
return $this->hasMany('App\Models\Replaced');
}
public function orders()
{
return $this->belongsTo('App\Models\Order');
}
public function products()
{
return $this->hasMany('App\Models\Product');
}
public function collis()
{
return $this->hasMany('App\Models\Colli');
}
}
Anyone that knows what can be the cause of this?
There is a spelling error on $order_datail = new OrderDetail;
Change it to: $order_detail = new OrderDetail;

lararvel uuid as primary key

I'm trying to set an uuid as primary key in a Laravel Model. I've done it setting a boot method in my model as stablished here so I don't have to manually create it everytime I want to create and save the model. I have a controller that just creates the model and saves it in database.
It is saved correctly in database but when controller returns the value of the id is always returned with 0. How can I make it to actually return the value that it is creating in database?
Model
class UserPersona extends Model
{
protected $guarded = [];
protected $casts = [
'id' => 'string'
];
/**
* Setup model event hooks
*/
public static function boot()
{
parent::boot();
self::creating(function ($model) {
$uuid = Uuid::uuid4();
$model->id = $uuid->toString();
});
}
}
Controller
class UserPersonaController extends Controller
{
public function new(Request $request)
{
return UserPersona::create();
}
}
You need to change the keyType to string and incrementing to false. Since it's not incrementing.
public $incrementing = false;
protected $keyType = 'string';
Additionally I have an trait which I simply add to those models which have UUID keys. Which is pretty flexible. This comes originally from https://garrettstjohn.com/articles/using-uuid-laravel-eloquent-orm/ and I added some small adjustments to it for issues which I have discovered while using it intensively.
use Illuminate\Database\Eloquent\Model;
use Ramsey\Uuid\Uuid;
/**
* Class Uuid.
* Manages the usage of creating UUID values for primary keys. Drop into your models as
* per normal to use this functionality. Works right out of the box.
* Taken from: http://garrettstjohn.com/entry/using-uuids-laravel-eloquent-orm/
*/
trait UuidForKey
{
/**
* The "booting" method of the model.
*/
public static function bootUuidForKey()
{
static::retrieved(function (Model $model) {
$model->incrementing = false; // this is used after instance is loaded from DB
});
static::creating(function (Model $model) {
$model->incrementing = false; // this is used for new instances
if (empty($model->{$model->getKeyName()})) { // if it's not empty, then we want to use a specific id
$model->{$model->getKeyName()} = (string)Uuid::uuid4();
}
});
}
public function initializeUuidForKey()
{
$this->keyType = 'string';
}
}
Hope this helps.
Accepted answer not worked for me on Laravel 9, but this way worked perfect, you can try it:
1- Create new Trait Class in project path app/Traits/IdAsUuidTrait.php (if you not found Traits folder create it, this is full code of this Class:
<?php
namespace App\Traits;
use Illuminate\Support\Str;
trait IdAsUuidTrait
{
public function initializeIdAsUuidTrait(): void
{
$this->keyType = 'string';
$this->id = Str::orderedUuid()->toString();
}
}
2- In any model you want to make id as UUID just call trait like this:
use App\Traits\IdAsUuidTrait;
class YourModelName extends Model
{
use IdAsUuidTrait;
...
That is it, now try to create, select, update any row in database by this model...

Call to undefined method Illuminate\Database\Query\Builder::save() on seed

I'm trying to create seeders to my models using seed and factory. My models have relationship one to many. When I run
php artisan db:seed --class=ChildTableSeeder
I get the following error:
In Builder.php line 2461:
Call to undefined method Illuminate\Database\Query\Builder::save()
Independently of the error the data seed is added to the target table.
My table's structure is like follow:
parents
- parentId
- name
- value
childs
- childId
- parentId
- views
- count
And my models:
//Parent.php
<?php
namespace App\Models\Api;
use Illuminate\Database\Eloquent\Model;
class Parent extends Model
{
protected $primaryKey = 'parentId';
public $incrementing = false;
protected $keyType = 'string';
}
//Child.php
<?php
namespace App\Models\Api;
use Illuminate\Database\Eloquent\Model;
class Child extends Model
{
protected $primaryKey = 'childId';
public $incrementing = false;
protected $keyType = 'string';
public function parents()
{
return $this->belongsTo('App\Models\Api\Parent', 'parentId', 'parentId');
}
}
Also see the Seed code
//ParentTableSeeder
factory(App\Models\Api\Child::class, 50)->create()->each(function ($u) {
$u->parents()->save(factory(App\Models\Api\Parent::class)->make());
});
Anyone has an idea what I'm doing wrong? or How to solve this issue?
You need to use associate() function insted of save()
Also parents() relationshiop's definition is wrong
public function parents()
{
return $this->belongsTo('App\Models\Api\Parent', 'parentId', 'childId');
}
Use the associate method instead of save when creating the relationship:
$p = factory(App\Models\Api\Parent::class)->create():
$u->parents()->associate($p);
$u->save();

how to get last id when a row was insert in laravel eloquent in Model

I've used setNotification method of model by initial data from Controller within a variable $data as array. I have used self:: in this method instead of used table or Notification::save() or $obj->save(). by this way I don't know how to get Id which the last id after insert was done in laravel because I used $this->attributes that it is the protected variable in Model.
class Notification extends Model
{
protected $table = 'notification';
public $timestamps = true;
private $_data = false;
public function setNotification($data)
{
if (is_array($data)) {
$this->attributes = $data;
self::save();
}
}
}
Try something like $this->attributes[id] after save() is executed.
I suggest You to use create method instead and return created object, so then You can access id property.
public function setNotification($data)
{
if (is_array($data)) {
return $this->create($data);
}
return null;
}

Laravel4 - Saving a model with multiple relationships/foreign keys

I've tried to understand a process of saving a model with multiple relationships but I still can't figure out how to do it "kosher" way.
To begin with - I have an Event model that belongs to a category (Eventcat) and a Location:
// Event.php
class Event extends Eloquent {
protected $table = 'events';
public function location()
{
return $this->belongsTo('Location');
}
public function eventcat()
{
return $this->belongsTo('Eventcat');
}
public function users()
{
return $this->belongsToMany('User');
}
}
// Location.php
class Location extends Eloquent
{
protected $table = 'locations';
public function events()
{
return $this->hasMany('Event');
}
}
// Eventcat.php
class Eventcat extends Eloquent
{
protected $table = 'eventcats';
public function events()
{
return $this->hasMany('Event');
}
}
I've seeded the database with a few categories and locations and now I trying to get events saving work. I thought that the $event->eventcat()->associate( $eventcat ) would work but I got a Call to undefined method eventcat() error.
public function postCreateEvent() {
$event = new Event();
$eventcat = Eventcat::find( Input::get('event-create-eventcat[]') );
$location = Location::find( Input::get('event-create-location[]') );
$event->title = Input::get('event-create-title');
$event->description = Input::get('event-create-description');
$event->price = Input::get('event-create-price');
$event->start_date = Input::get('event-create-start_date');
$event->end_date = Input::get('event-create-end_date');
$event->eventcat()->associate( $eventcat );
$event->location()->associate( $location );
$event->save();
}
I've read the documentation, API and a few threads here but I still can't figure out the best way to deal with this.
Thanks for replies!
I would actually bet that you have a conflict in your class name. Laravel contains an Event class and I wonder if that isn't what's being called in your code. As a quick test, you could rename your class FooEvent and see if it works.
The best solution is probably namespacing your model (see http://chrishayes.ca/blog/code/laravel-4-methods-staying-organized for a quick intro) so that your model can still be called Event without conflicting with the builtin class.

Resources