I am trying to abstract my models using a single base class. I have three models that inherit from the same base:
Repair
Inspection
Purchase
I am able to successfully create and persist the models to the DB, but when fetching I get a blank screen, no errors are thrown. When I remove the $with attribute everything seems to work.
Heres the code:
abstract class ItemType extends Model
{
public $timestamps = false;
protected $with = ['details'];
public function details()
{
return $this->morphOne(Item::class, 'type', 'item_details_type', 'item_details_id', 'id');
}
}
class Repair extends ItemType
{
protected $table = 'repairs';
protected $guarded = ['id', 'created_at', 'updated_at'];
protected $morphClass = self::class;
}
class Inspection extends ItemType {}
class Purchase extends ItemType {}
In the end I decided to use morphTo relationships without the abstract class to solve the issue.
Related
I'm try to create a relationship between albums and photos (an Album has many photos). Below is my controller and what my models look like. Interesting enough, the reverse relationship photo->album (belongsTo) works fine! but the album->photos returns an empty collection.
## The hasMany relationship does NOT work... I get an empty collection
<?php
class AlbumController extends BaseController
{
public function show(Request $request, $album_id)
{
$album = Album::find($album_id);
dd($album->photos);
}
}
## Results:
# Collection {#418
# items: []
# }
## The belgonsTo relationship works
<?php
class PhotoController extends BaseController
{
public function show(Request $request, $photo_id)
{
$photo = Photo::find($photo_id);
dd($photo->album);
}
}
<?php
namespace App;
use DB;
use Jenssegers\Mongodb\Eloquent\SoftDeletes;
use Moloquent;
class Album extends Moloquent
{
use RecordActivity, SoftDeletes;
protected $connection = 'mongodb';
protected $table = 'albums';
protected $collection = 'albums';
protected $primaryKey = "_id";
protected $dates = ['deleted_at'];
protected $fillable = ['user_id','name','is_private'];
public function photos()
{
// Neither seems to work
//return $this->embedsMany('Photo');
return $this->hasMany('App\Photo');
}
}
<?php
namespace App;
use DB;
use Jenssegers\Mongodb\Eloquent\SoftDeletes;
use Moloquent;
class Photo extends Moloquent
{
use RecordActivity, SoftDeletes;
protected $connection = 'mongodb';
protected $table = 'photos';
protected $collection = 'photos';
protected $primaryKey = "_id";
protected $dates = ['deleted_at'];
protected $fillable = ['album_id', 'user_id', 'name', 'folder', 'is_private', 'caption'];
protected $hidden = [];
// user and album belongsTo works
public function user()
{
return $this->belongsTo('App\User');
}
public function album()
{
return $this->belongsTo('App\Album');
}
}
The issue had to do with the fact that my IDs were ObjectID and it seems to be an issue with Jessengers Laravel MongoDB Drivers... we have actually decided to move back to MariaDB to fully utilize Eloquent/Relationships
I did the same thing as yours and i found that nothing wrong with Mongodb. Because Mongodb defined the "_id" as primary key and that's the reason it couldn't get the correct relationship: belongsTo and hasMany. So i did a small change by declared the $primaryKey = "id" on the top of parent Model and it worked fine
this worked for me.
/**
* #return HasMany
*/
public function tasks(): HasMany
{
return $this->hasMany(ProjectTask::class, 'project_id', 'idAsString');
}
I have four tables and I am giving my table structure here
user_work['id', 'user_id', 'work_id']
work_sectors['id', 'name', 'status']
works['id', 'work_sector_id', 'work_type_id', 'work_duration_id', 'name']
users['id', ...]
And My Models are
class User extends Eloquent implements UserInterface, RemindableInterface
{
use UserTrait, RemindableTrait;
protected $table = 'users';
public function work()
{
return $this->belongsToMany('Work', 'user_work');
}
}
class Work extends \Eloquent {
protected $fillable = [];
protected $table_name = 'works';
public $timestamps = false;
public function user()
{
return $this->belongsToMany('User', 'user_work');
}
public function sector()
{
return $this->belongsTo('WorkSector', 'work_sector_id');
}
}
In my controller I have written this code
$user = User::with('language')->with('work')->find($userId);
Here I need name of work_sector table but probably I have written wrong code to get the sector name.
So please help me to write a proper function in this eloquent method in laravel 4.2.
Sometimes you may wish to limit the attributes that are included in your model's array or JSON form, such as passwords. To do so, add a hidden property definition to your model:
class User extends Model {
protected $hidden = ['password'];
}
This is model specific.
Is there any method to hide globally?
ie,I want to hide deleted_at and created_by from all model json result.
The easiest way to do that is by creating a base model. Like this:
class BaseModel extends Model {
protected $hidden = ['deleted_at', 'created_by'];
}
And then all your models extend from that:
class User extends BaseModel {
}
Note that this way if you wanted to add some hidden fields for a specific model you would have to as well specify those two global hidden attributes:
class User extends BaseModel {
protected $hidden = ['deleted_at', 'created_by', 'password'];
}
If that bothers you, you could merge the global attributes in from the contructor:
class BaseModel extends Model {
private $globalHidden = ['deleted_at', 'created_by'];
public function __construct(array $attributes = array()){
$this->hidden = array_merge($this->globalHidden, $this->hidden);
parent::__construct($attributes);
}
}
I'm trying to upgrade my existing Laravel 4 project to version 5.
Model relationships are not working fine. Every time I try to access a property from property_price table it returns null.
My models are located in App/Models directory.
Property Model
class Property extends \Eloquent {
protected $guarded = array('id');
protected $table = 'properties';
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $softDelete = true;
public function propertyPrice()
{
return $this->hasOne('PropertyPrice','pid');
}
}
PropertyPrice Model
class PropertyPrice extends \Eloquent {
protected $guarded = array('id');
protected $table = 'property_pricing';
public function property()
{
return $this->belongsTo('Property');
}
}
Usage
$property = Property::find($id);
$price = $property->property_price->per_night_price; // null
The code is working fine in Laravel 4.
You need to specify namespace in relation methods.
If you're using php5.5+ then use ::class constant, otherwise string literal:
// App\Models\PropertyClass
public function property()
{
return $this->belongsTo(Property::class);
// return $this->belongsTo('App\Models\Property');
}
// App\Models\Property model
public function propertyPrice()
{
return $this->hasOne(PropertyPrice::class,'pid');
// return $this->hasOne('App\Models\PropertyPrice','pid');
}
Of course you need to namespace the models accordingly:
// PSR-4 autoloading
app/Models/Property.php -> namespace App\Models; class Property
Is possibile to use inheritance in laravel model? I explain:
is possible to exend a model, which extends eloquent class?
class A extends Eloquent
{
}
class B extends A
{
}
A e B are also 2 different tables and B has A_id as foreignkey and other fields.
How could be the constructor of class B?
is it a ragionable solution or better use hasOne relationship?
no every A object are also B object. Es. user and teacher
Thank you
I’m having difficulty understanding your supplementary details, but in answer to the actual question: yes, it is possible to extend Eloquent models.
<?php
class User extends \Eloquent {
protected $table = 'users';
}
class Student extends User {
protected $table = 'students';
}
Be warned though, that any methods (such as relations, scopes etc) will propagate to the extending class. If this is not desired, then create a base class that has the minimum of what you need, and then sub-class it with your specific types, i.e. Student, Administrator etc.
Another approach is to use interfaces. So if you know models need the same attributes but will say, have different relations; then you can create an interface to add those constraints:
<?php
interface UserInterface {
public function getName();
}
class User extends \Eloquent implements UserInterface {
protected $table = 'users';
public function getName()
{
return $this->name;
}
}
class Student extends \Eloquent implements UserInterface {
protected $table = 'students';
public function getName()
{
return $this->name;
}
public function courses()
{
return $this->belongsToMany('Course');
}
public function grades()
{
return $this->hasMany('Grade');
}
}
I resolve with
class A extends Eloquent
{
protected $table = 'a';
}
class B extends A
{
protected $table = 'b';
protected $primaryKey = 'a_id';
}
but in the main function:
$f = B::find(1);
$f->method();
where the method() is a method of A class,
the system gives to me an mysql error:
select * from `C` where `C`.`B_id` = 1
the error is B_id. It should be A_id cause the method should be applied from subobject of the class, not from the class