Lumen Eloquent save() don't update data at database - php

I have buyer model, but when i want to change current it's data and save it, it won't save. $buyer->save() return 1 but data at my database won't change.
P.S.
My database has id, created_at and updated_at fields. And $buyer is not empty, it's object with data that i request ('pCode', 'banned', 'hwid')
My code
namespace App\Http\Controllers;
use App\TGOBuyer as Buyer;
class SubController extends Controller
{
public function ban($key){
$buyer = Buyer::where('pCode', $key)->select('pCode', 'banned', 'hwid')->first();
if (!$buyer || $buyer->banned)
return response()->json(['wrong' => 'key']);
$buyer->comment = 'test';
$buyer->banned = 1;
$buyer->save();
}
}
Buyer model
namespace App;
use Illuminate\Database\Eloquent\Model;
class TGOBuyer extends Model {
protected $table = 'buyers';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'banned', 'comment', 'pCode', 'hwid'
];
}
Update
I tryed to return $buyer->id and it gives me null, i don't get it why it happens.
This is my db
CREATE TABLE IF NOT EXISTS `buyers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pCode` varchar(20) NOT NULL,
`banned` tinyint(1) NOT NULL DEFAULT '0',
`comment` text NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `pCode` (`pCode`),
UNIQUE KEY `id_2` (`id`),
KEY `id` (`id`),
KEY `hwid` (`hwid`),
KEY `pID` (`pID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=22468 ;

I get it. I just need to include id to my select query. Now all work's fine.
$buyer = Buyer::where('pCode', $key)->select('id', 'pCode', 'banned', 'hwid')->first();

Related

Eloquent hasMany doesn't load collection

I'm relatively new to eloquent, and have problems loading data from a hasMany relation in an app that uses eloquent as the database layer. My (simplified) code is as follows:
use Illuminate\Database\Eloquent\Model;
class Answer extends Model{
protected $table = 'answer';
public $timestamps = false;
public $incrementing = false;
protected $fillable = [
"nerdId",
"invitationid",
"eatingno",
"price",
"haspaid",
"attending",
"noeating",
];
public function topping() {
return $this->hasMany(AnswerTopping::class, 'answerid');
}
}
class AnswerTopping extends Model{
protected $table = 'eating';
public $timestamps = false;
protected $fillable = [
'answerid',
'toppingid',
'add'
];
public function answer() {
return $this->belongsTo(Answer::class);
}
}
The SQL Schema is like below
CREATE TABLE `answer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nerdid` int(11) NOT NULL,
`invitationid` int(11) NOT NULL,
`eatingno` tinytext,
`price` float NOT NULL,
`haspaid` tinyint(4) NOT NULL,
`attending` tinyint(1) NOT NULL DEFAULT '0',
`noeating` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2119 DEFAULT CHARSET=utf8;
CREATE TABLE `eating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`answerId` int(11) NOT NULL,
`toppingid` int(11) NOT NULL,
`add` tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=280 DEFAULT CHARSET=utf8;
I then do the following query:
$answer = Answer::with('topping')->find(32);
return $answer->toJson());
This results in a json like the following
{"id":32,"nerdid":1,"invitationid":54,"eatingno":"51","price":60,"haspaid":1,"attending":2,"noeating":0,"topping":[]}
Raw SQL query shows me that I do have data in the relation, so it should return more in "topping".
UPDATE
Checking sql queries in mysql (Setting it up for logging), I see that it actually do the expected queries on the database:
select * from `answer` where `answer`.`id` = 32 limit 1;
select * from `eating` where `eating`.`answerid` in (32);
Manually executing the SQL are giving me 2 entries in the eating table. But they are not showing up on the upper "Answer" json.
Found the culprit.. db schema for the "eating" table, had answerId (uppercase I), and the relation in hasMany used answerid (lowercase i), which apparently confused eloquent..
Now I get the expected json..

Laravel eager loading error "Trying to get property of non-object in .../BelongsToMany.php"

Laravel 5.8
I'm having an issue getting eager loading to work on some models but not on others.
Using artisan tinker I can run;
$p = App\Programme::find(34)->reviews
and get the correct result. If I change this to;
$p = App\Programme::with('reviews')->find(34)
So that the reviews are eager loaded, it fails with the error
PHP Notice: Trying to get property of non-object in .../vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php on line 301
output from artisan with query log, bindings and execute time
$p = App\Programme::with('destinations', 'reviews')->find(34)
"select * from `programmes` where `programmes`.`id` = ? and `programmes`.`deleted_at` is null limit 1"
array:1 [
0 => 34
]
1.08
"select `destinations`.*, `programme_destination`.`programme_id` as `pivot_programme_id`, `programme_destination`.`destination_id` as `pivot_destination_id`, `programme_destination`.`created_at` as `pivot_created_at`, `programme_destination`.`updated_at` as `pivot_updated_at` from `destinations` inner join `programme_destination` on `destinations`.`id` = `programme_destination`.`destination_id` where `programme_destination`.`programme_id` in (34)"
[]
0.88
"select `reviews`.*, `programme_reviews`.`programme_id` as `pivot_programme_id`, `programme_reviews`.`review_id` as `pivot_review_id`, `programme_reviews`.`created_at` as `pivot_created_at`, `programme_reviews`.`updated_at` as `pivot_updated_at` from `reviews` inner join `programme_reviews` on `reviews`.`id` = `programme_reviews`.`review_id` where `programme_reviews`.`programme_id` in (34)"
[]
0.85
The final query if run manually works just fine.
I can run the exact same two commands using either the User or Destination models and get a successful response. So there must be something different about the relationship of $programme->reviews when compared to $programme->user or $programme->destinations
Here are my models (trimmed to the relevant functions);
App\BaseModel
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use OwenIt\Auditing\Contracts\Auditable;
use Log;
use DB;
class BaseModel extends Model
{
protected $guarded = ['alias', 'created_at', 'updated_at', 'deleted_at', 'slug'];
public $custom_attributes = [];
public $index_attributes = ['alias', 'user'];
public function alias()
{
return $this->morphOne('App\Alias', 'aliased');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
App\Programme
<?php
namespace App;
use App\BaseModel;
use Illuminate\Database\Eloquent\SoftDeletes;
use OwenIt\Auditing\Contracts\Auditable;
use Log;
class Programme extends BaseModel implements Auditable
{
use SoftDeletes;
use \OwenIt\Auditing\Auditable;
protected $table = 'programmes';
protected $dates = ['deleted_at'];
function __construct(array $attributes = array())
{
parent::__construct($attributes);
}
public function destinations()
{
return $this->belongsToMany('App\Destination', 'programme_destination')
->withTrashed()
->withTimestamps();
}
public function reviews()
{
return $this->belongsToMany('App\Review', 'programme_reviews')
->withTrashed()
->withTimestamps();
}
}
App\Review
<?php
namespace App;
use App\BaseModel;
use Illuminate\Database\Eloquent\SoftDeletes;
use OwenIt\Auditing\Contracts\Auditable;
use Log;
class Review extends BaseModel implements Auditable
{
use SoftDeletes;
use \OwenIt\Auditing\Auditable;
protected $fillable = ['title', 'name', 'first_name', 'last_name', 'review_type', 'email_address', 'created_at'];
function __construct(array $attributes = array())
{
parent::__construct($attributes);
}
public function programmes()
{
return $this->belongsToMany('App\Programme', 'programme_reviews')
->withTrashed()
->withTimestamps();
}
}
I can run $p = App\Programme::with('destinations', 'alias')->find(34) successfully. Here's the model for destinations
App\Destination
<?php
namespace App;
use App\BaseModel;
use Illuminate\Database\Eloquent\SoftDeletes;
use OwenIt\Auditing\Contracts\Auditable;
class Destination extends BaseModel implements Auditable
{
use SoftDeletes;
use \OwenIt\Auditing\Auditable;
protected $table = 'destinations';
protected $dates = ['deleted_at'];
function __construct(array $attributes = array())
{
parent::__construct($attributes);
}
public function programmes()
{
return $this->belongsToMany('App\Programme', 'programme_destination')
->withTrashed()
->withTimestamps();
}
}
It seems the relationship works based on the first artisan command, so why does this not work when eager loading?
For reference here are the database create codes;
programmes
CREATE TABLE `programmes` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(191) NOT NULL COLLATE 'utf8_unicode_ci',
`destination_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`user_id` INT(10) UNSIGNED NOT NULL DEFAULT '1',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`deleted_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `programmes_user_id_foreign` (`user_id`),
INDEX `programmes_destination_id_foreign` (`destination_id`),
CONSTRAINT `programmes_destination_id_foreign` FOREIGN KEY (`destination_id`) REFERENCES `destinations` (`id`),
CONSTRAINT `programmes_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;
reviews
CREATE TABLE `reviews` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`name` VARCHAR(191) NOT NULL COLLATE 'utf8_unicode_ci',
`first_name` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`last_name` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`email_address` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`deleted_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;
programme_reviews - many to many
CREATE TABLE `programme_reviews` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`programme_id` INT(10) UNSIGNED NOT NULL,
`review_id` INT(10) UNSIGNED NOT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `programme_reviews_review_id_foreign` (`review_id`),
INDEX `programme_id` (`programme_id`),
CONSTRAINT `programme_reviews_programme_id_foreign` FOREIGN KEY (`programme_id`) REFERENCES `programmes` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `programme_reviews_review_id_foreign` FOREIGN KEY (`review_id`) REFERENCES `reviews` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;
destinations
CREATE TABLE `destinations` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(191) NOT NULL COLLATE 'utf8_unicode_ci',
`user_id` INT(10) UNSIGNED NOT NULL DEFAULT '1',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`deleted_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `destinations_parent_id_index` (`parent_id`),
INDEX `destinations_user_id_foreign` (`user_id`),
CONSTRAINT `destinations_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;
programme_destinations one to many
CREATE TABLE `programme_destination` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`programme_id` INT(10) UNSIGNED NOT NULL,
`destination_id` INT(10) UNSIGNED NOT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `programme_destination_programme_id_foreign` (`programme_id`),
INDEX `programme_destination_destination_id_foreign` (`destination_id`),
CONSTRAINT `programme_destination_destination_id_foreign` FOREIGN KEY (`destination_id`) REFERENCES `destinations` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `programme_destination_programme_id_foreign` FOREIGN KEY (`programme_id`) REFERENCES `programmes` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;
The only real difference between $programme->destinations and $programme->reviews is that reviews is a many to many relationship.
So I've found the answer to this niggling query thanks to outside help.
My question as is would not have been answerable, as the problem actually existed with a $pivot class variable I had assigned on the Programme model (and removed for the post to attempt to shorten it).
This variable clashed with Laravel's internal workings, which seems quite obvious now I know about it.
Changing $pivot to anything else allowed the relationship to be eager loaded correctly.
It's unlikely someone will have the same issue as me, but who knows, it may help someone avoid the error I encountered.
Just adding another answer in case it helps someone searching for this problem.
I just spent an hour trying to work out why I was getting "Trying to get property of non-object" when eager-loading a many-to-many relationship with
Document::where('id',$id)->with('authors')->first();
I tracked the problem down to the Document model which contained a pivot table alias and a specified pivot field:
public function authors() {
return $this->belongsToMany('App\User')->withPivot('role')->as('role');
}
When I swapped the order of the methods and renamed the alias, it worked.
public function authors() {
return $this->belongsToMany('App\User')->as('author_role')->withPivot('role');
}
The "Trying to get property of non-object" error was completely unhelpful in debugging this error. But making the change above was enough to resolve it.

cakephp 3 get method not returning fields

CakePHP 3.5.
PHP 7.2.8
Docker env
mysql Ver 15.1 Distrib
10.1.26-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
CREATE TABLE `feedback_calls` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`USER_ID` bigint(20) DEFAULT NULL,
`TENDER_ID` bigint(20) DEFAULT NULL,
`MANAGER_ID` bigint(20) DEFAULT NULL,
`TITLE` varchar(255) DEFAULT NULL,
`STATUS` varchar(255) DEFAULT NULL,
`EVENT_START` datetime DEFAULT NULL,
`EVENT_END` datetime DEFAULT NULL,
`CREATED_ON` datetime DEFAULT NULL,
`CREATED_BY` bigint(20) DEFAULT NULL,
`LOCKED_TIME` datetime DEFAULT NULL,
`UPDATED_ON` datetime DEFAULT NULL,
`UPDATED_BY` bigint(20) DEFAULT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID_UNIQUE` (`ID`),
KEY `FK_Tender_idx` (`TENDER_ID`),
KEY `FK_FeedbackCalls_User_idx` (`USER_ID`),
CONSTRAINT `FK_Tender` FOREIGN KEY (`TENDER_ID`) REFERENCES `dls_tender` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_FeedbackCalls_User` FOREIGN KEY (`USER_ID`) REFERENCES `dir_user` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8
MySQl table contains:
Model:
<?php
namespace App\Model\Table;
use Cake\Datasource\EntityInterface;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\Network\Exception\NotFoundException;
use Cake\Log\Log;
use Cake\Database\Type;
use Cake\I18n\Time;
final class FeedbackCallsTable extends Table
{
use VirtualFieldsTrait;
/**
* #param array $config The configuration for the Table.
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('feedback_calls');
$this->setDisplayField('ID');
$this->setPrimaryKey('ID');
}
public function index($id = null)
{
$eventData = $this->get($id);
log::debug($eventData);
}
}
When I use cakephp 3 get method I get MANAGER_ID value as null.
log::debug("ID is ::".$id);
$eventData = $this->get($id);
log::debug("EventData is :: ");
log::debug($eventData);
output::
Additional info: It is also not saving the field on update operation. I've cleared the cache tables and also tried to find method as well but got same results. Any solution/ advise is welcome. Thanks.

Laravel custom morph relationship

I'd like to use Laravel Eloquent Polymorphic Relationships however it doesn't seem to be setup to work with my table structure.
Essentially I have a gamedata table which includes all the different types of gamedata (nation, league, team, player etc). For each type I have multiple tables with information separated by game_id. So there would be one row for the nation "England" in the gamedata table, which has 7 corresponding rows in the nations table with data from 7 different game_ids.
I'd like to be able to select some rows from the gamedata table and their corresponding rows from the appropriate table depending on it's type.
This is easy enough to do on a one to one relationship, but seems impossible to do with a one to many relationship.
Here is the gamedata table.
CREATE TABLE `gamedata` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`data_type` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `data_id` (`data_id`,`type`),
FULLTEXT KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
And then lots of tables like this (lots of columns removed for ease of reading):
CREATE TABLE `nations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`game_id` tinyint(3) unsigned NOT NULL,
`gamedata_id` int(10) unsigned NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`short_name` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
/* more specific columns removed for ease of reading */
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `leagues` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`game_id` tinyint(3) unsigned NOT NULL,
`gamedata_id` int(10) unsigned NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`short_name` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
/* more specific columns removed for ease of reading */
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `teams` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`game_id` tinyint(3) unsigned NOT NULL,
`gamedata_id` int(10) unsigned NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`short_name` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
/* more specific columns removed for ease of reading */
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
So some rows on the gamedata table might look like this:
(144, 'nation', 'Some Nation'),
(145, 'nation', 'Another Nation'),
(146, 'league', 'Some League'),
(147, 'league', 'Another League'),
(148, 'team', 'Some Team'),
(149, 'team', 'Another Team');
So I should be able to do a polymorphic relationship from the "data_type" column and the "data_id" column to get the corresponding row from the appropriate table.
But none of the built in relationships (morphTo, morphMany, morphedByMany) etc seem to be able to handle it.
It seems like what I want is the morphTo() relationship but it seems to restrict itself to only returning one related model. All the relationships that accept multiple models require a specific model to be defined.
// This would work fine if I only wanted one related model. "data_type" being the class and "id" corresponding to "gamedata_id" on relevent table.
$this->morphTo('data');
// These require me to be explicit about the class instantiating rather than using from the "data_type" column
$this->morphMany(???, 'data');
$this->morphToMany(???, 'data');
$this->morphedByMany(???, 'data');
Is there a way to do this using the existing Laravel Relationships? Or is there a simple way to create my own relationship class based on morphTo that would suit my needs?
I think i've come up with a custom solution by extending the morphTo class.
namespace App;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\MorphTo;
/**
* #mixin \Illuminate\Database\Eloquent\Builder
*/
class MorphHasMany extends MorphTo
{
/**
* Get the results of the relationship.
*
* #return mixed
*/
public function getResults()
{
return $this->ownerKey ? $this->query->get() : null;
}
/**
* Match the results for a given type to their parents.
*
* #param string $type
* #param \Illuminate\Database\Eloquent\Collection $results
* #return void
*/
protected function matchToMorphParents($type, Collection $results)
{
$ownerKeyName = $this->ownerKey ?: $results->first()->getKeyName();
foreach ($results->groupBy($ownerKeyName) as $ownerKey => $result) {
if (isset($this->dictionary[$type][$ownerKey])) {
foreach ($this->dictionary[$type][$ownerKey] as $model) {
$model->setRelation($this->relation, $result);
}
}
}
}
}
The morphTo() class already returns a Collection of results, but either uses first() or multiple instances of setRelation() to mean there is only one set. By overloading getResults() and matchToMorphParents() I can modify this behaviour to allow setting of a Collection instead.
In order to define the relationship i'll need a custom morphHasMany() method. This could be added to a base Model.php that extends Eloquent\Model.
/**
* Define a polymorphic has many relationship.
*
* #param string $name
* #param string $type
* #param string $id
* #param string $ownerKey
* #return MorphHasMany
*/
public function morphHasMany($name = null, $type = null, $id = null, $ownerKey = null)
{
// If no name is provided, we will use the backtrace to get the function name
// since that is most likely the name of the polymorphic interface. We can
// use that to get both the class and foreign key that will be utilized.
$name = $name ?: $this->guessBelongsToRelation();
list($type, $id) = $this->getMorphs(
Str::snake($name), $type, $id
);
// If the type value is null it is probably safe to assume we're eager loading
// the relationship. In this case we'll just pass in a dummy query where we
// need to remove any eager loads that may already be defined on a model.
if (empty($class = $this->{$type})) {
return new MorphHasMany($this->newQuery()->setEagerLoads([]), $this, $id, $ownerKey, $type, $name);
} else {
$instance = $this->newRelatedInstance(
static::getActualClassNameForMorph($class)
);
return new MorphHasMany($instance->newQuery(), $this, $id, $ownerKey ?? $instance->getKeyName(), $type, $name);
}
}
Then simply define it just like the usual morphTo() method.
public function data()
{
return $this->morphHasMany();
}
Or in my case:
public function data()
{
return $this->morphHasMany('data', 'data_type', 'id', 'gamedata_id');
}
So far no problems, but of course I may run into some in the future.

Get nested associated records in Laravel 5.1

I have three Database Tables.
CREATE TABLE `tblprojecttype` (
`ProjectTypeID` int(11) NOT NULL,
`ProjectType` varchar(30) NOT NULL,
`Description` varchar(500) NOT NULL,
`IsActive` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `tblprojecttypecurrencyprice` (
`ProjectTypeCurrencyID` int(11) NOT NULL,
`CurrencyID` int(11) NOT NULL,
`ProjectTypeID` int(11) NOT NULL,
`Price` decimal(10,0) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `tblcurrency` (
`CurrencyID` int(11) NOT NULL,
`Currency` varchar(100) NOT NULL,
`IsActive` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Models
class Currency_Model extends Model
{
protected $table = "tblcurrency";
protected $primaryKey = "CurrencyID";
public $timestamps = false;
}
class ProjectType_Model extends Model
{
protected $table = "tblprojecttype";
protected $primaryKey = "ProjectTypeID";
public $timestamps = false;
public function projecttypecurrencyprice()
{
return $this->hasOne('\App\Models\ProjectTypeCurrencyPrice_Model',
"ProjectTypeID");
}
}
class ProjectTypeCurrencyPrice_Model extends Model
{
protected $table = "tblprojecttypecurrencyprice";
protected $primaryKey = "ProjectTypeCurrencyID";
public $timestamps = false;
public function Currency()
{
return $this->hasOne('\App\Models\Currency_Model', "CurrencyID");
}
}
There is CurrencyID relationship and ProjectTypeID relationship
What I am trying ?
In my Laravel 5.1 code, I am trying to achive below sql statement so that I can get projecttypecurrencyprice records for each ProjectType record. Finally it should also show records from currency Table for each projecttypecurrencyprice record
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice")
->with("projecttypecurrencyprice.Currency")
->get();
What's the Problem ?
I am not able to get Currency records for each projecttypecurrencyprice record.
For ProjectTypeCurrencyPrice_Model you should change Currency relationship this way:
public function Currency()
{
return $this->belongsTo('\App\Models\Currency_Model', "CurrencyID");
}
because you have CurrencyId column in tblprojecttypecurrencyprice and you don't have any connection to ProjectTypeCurrencyPrice_Model in tblcurrency.
And to get data instead of:
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice")
->with("projecttypecurrencyprice.Currency")
->get();
you can omit 1st with:
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice.Currency")
->get();
By the way if you start this project, you should consider changes in your database structure and read about PSR in PHP - you should rather not use ProjectTypeCurrencyPrice_Model as your model name if you really don't have to, same for ProjectTypeID columns in MySQL

Categories