Can't get hasmany tables in laravel 5.1 eloquent - php

I am having problem in getting the hasmany relationship data in Laravel eloquent.
AModel hasmany BModel
AModel hasmany CModel
AModel has function:
Public function bmodels(){
return hasMany('BModel');
}
Public function cmodels(){
return hasMany('CModel');
}
BModel has function:
Public function bmodels(){
return belongsTo('AModel', amodel_id);
}
CModel has function:
Public function cmodels(){
return belongsTo('AModel',amodel_id);
}
Now i am trying to get it like this
$amodels = AModel::with('bmodels','cmodels')
->where('status_id','2200')
->whereIn('eventstatus_id',['1','2'])
->get();
and now i want to test this in the for loop.
foreach($amodels as $amodel){
$bmodels = $model->bmodels();
if ($amodel && $amodel->end < Carbon::now()){
foreach ($bmodels as $bmodel){
$cmodels = $amodel->cmodels();
foreach($cmodels as $cmodel){
if ($bmodel->id !== $cmodel->reservation_id || $cmodel->reservation_id != null ){
array_push($reservation_needed_to_enter,$bmodel->id);
}
}
}
}
}

You should make changes in your Models, use $this to use belongsTo and hasMany,like
public function bmodels(){
return $this->belongsTo('App\AModel','amodel_id');
}
public function bmodels(){
return $this->hasMany('App\BModel');
}
Just Edited your foreach loop, use $amodel->bmodels instead of $amodel->bmodels()
foreach($amodels as $amodel){
$bmodels = $amodel->bmodels;
if ($amodel && $amodel->end < Carbon::now()){
foreach ($bmodels as $bmodel){
$cmodels = $amodel->cmodels;
foreach($cmodels as $cmodel){
if ($bmodel->id !== $cmodel->reservation_id || $cmodel->reservation_id != null ){
array_push($reservation_needed_to_enter,$bmodel->id);
}
}
}
}
}

replace this two functions in your AModel
Public function bmodels(){
return hasMany('BModel');
}
Public function cmodels(){
return hasMany('CModel');
}
with
public function bmodels(){
return $this->hasMany('App\BModel');
}
public function cmodels(){
return $this->hasMany('App\CModel');
}
and these functions in BMOdel and CModel as
public function bmodels(){
return $this->belongsTo('App\AModel','amodel_id');
}
public function cmodels(){
return $this->belongsTo('App\AModel','amodel_id');
}

If your models are stored at the default directory you should probably do this instead:
public function bmodels()
{
return $this->hasMany('App\BModel');
}
Do you have a function in AModel named cmodels if not this could be the problem. Because you are trying to get AModel::with('bmodels','cmodels') but if one of those isn't there it is not going to work.
And this if ($amodel && $amodel->end < Carbon::now()){ doesn't make sense to me. Because $amodel will alwasy be an instance of Eloquent\Model and never false or whatever you are trying to check there. But maybe it has a purpose..
How to accces your BModel in your .blade file:
#foreach($aModel->bmodels() as $bModel)
{{$bModel->id}}
#endforeach()

Related

Filtering collection by model custom method

I'm using Laravel for a project and i want to filter a collection based on custom method written in the model:
Controller:
$models= Produs::with('categorie')
->with('poza')
->with('element_extra.extras')
->get()
->where('id_stare', 1)
->where('categorie.id_restaurant', $idRestaurant)
->groupBy('categorie.denumire');
$produse = $models->filter(function ($produs, $key) {
return $produs->isAvailable();
})->values();
Model:
class Produs extends Model
{
protected $table = "elemente";
public $timestamps = false;
public function isAvailable(){
if(...something....){
return false;
}else{
return true;
}
}
This is what i get:
BadMethodCallException
Method Illuminate\Database\Eloquent\Collection::isAvailable does not exist.
You need to add keyword scope to your method
public function scopeIsAvailable($query) {
return $query->where('active', true);
}
and after that call it like this
$models= Produs::isAvailable()...
:: double colon usage is for static functions.
try to use
public static function isAvailable(){}

How can I filter this with eloquent

I try to filter SurveyQuestionnaire which have Answer = 'poor' and their Questionnaire have step = 'rating'.
I've tried to look through the documentation of Eloquent and I've found nothing help.
This is my models.
class Questionnaire extends Model {
...
public function surveysQuestionnaires() {
return $this->hasMany(SurveyQuestionnaire::class, 'question_id');
}
public function answers() {
return $this->hasMany(Answer::class, 'question_id');
}
public function questionnaires() {
return $this->hasMany(QuestionnaireTranslation::class, 'question_id' );
}
}
class SurveyQuestionnaire extends Model {
public function survey() {
return $this->belongsTo(Survey::class ,'survey_id');
}
public function questionnaires() {
return $this->belongsTo(Questionnaire::class, 'question_id');
}
public function answer() {
return $this->belongsTo(Answer::class, 'answer_id');
}
}
Well, the hasMany method returns query builder, so you can simply add some conditions:
public function surveysQuestionnaires() {
return $this->hasMany(SurveyQuestionnaire::class, 'question_id')->where('Answer', 'poor');
}
Also, you can read this link Constraining Eager Loads and add your conditions manually after taking an instance of your model:
$items = App\Questionnaire::with(['surveysQuestionnaires' => function ($query) {
$query->where('Answer', 'poor');
}])->get();

2 foreign keys on one column in laravel 5.2

here's my database schema
and I have these models:
Admin
User
Bet
Match
Team
I'm confused how to define the relationShip between matches and teams in models
here Is what I did till now...
User.php
public function bets()
{
return $this->hasMany('\App\Bet');
}
Bet.php
public function user()
{
return $this->belongsTo('\App\User');
}
public function match()
{
return $this->belongsTo('\App\Match');
}
Match.php
public function bets()
{
return $this->hasMany('\App\Bet');
}
//?????????????
Team.php
//?????????????
actually what I need Is the code that should be placed instead of //???... in both Team.php and Match.php so that I can easily do such things...
$team->matches();
$match->team1();
$match->team2();
thanks
It should be something like this:
Match.php
public function team1()
{
return $this->belongsTo('\App\Team', 'team1_id');
}
public function team2()
{
return $this->belongsTo('\App\Team', 'team2_id');
}
Team.php
public function matches()
{
return $this->hasMany('\App\Match', 'team1_id')
->orWhere('team2_id', $this->id);
}
You can specify which column should be targeted for each relationship:
public function team1() {
return $this->belongsTo('\App\Match', 'team1_id');
}
public function team2() {
return $this->belongsTo('\App\Match', 'team2_id');
}
Let me know if this helps.
It would be something like this. Give it a try.
Match.php
public function team1(){
return $this->belongsTo('App\Team', 'team1_id');
}
public function team2(){
return $this->belongsTo('App\Team', 'team2_id');
}
Team.php
public function matches1(){
return $this->hasMany('App\Match', 'team1_id', 'id');
}
public function matches2(){
return $this->hasMany('App\Match', 'team2_id', 'id');
}

Laravel return Illegal offset type when I trie return a model

I'm working with a large json that returns several data from the database and I need to return an integer model that does not have any kind of relationship, I just need to return all the records that LampModels model with this great json. But Laravel always returns me Illegal offset type.
Controller
public function showAllUdiJson()
{
$allLamps = LampModels::all();
return Ilumination::with('street')
->with('neighborhood')
->with('iluminationinfo')
->with('economyplan')
->with('lamp')
->with('reactor')
->with('aluminumcable')
->with('steelconduit')
->with('alllamps', $allLamps)
->with('ticket')->get();
}
LampModels
<?php
class LampModels extends \Eloquent {
protected $fillable = [];
protected $table = 'lampmodel';
}
Illumination
<?php
class Ilumination extends \Eloquent {
protected $fillable = [];
protected $table = 'ilumination';
public function street()
{
return $this->belongsTo('street');
}
public function neighborhood()
{
return $this->hasOne('neighborhood', 'id');
}
public function iluminationinfo()
{
return $this->hasOne('iluminationinfo');
}
public function ticket()
{
return $this->hasMany('ticket');
}
public function economyplan()
{
return $this->hasOne('economyplan', 'id' ,'street_id');
}
public function lamp()
{
return $this->hasOne('lamp', 'id');
}
public function reactor()
{
return $this->hasOne('reactor', 'id');
}
public function aluminumcable()
{
return $this->hasOne('aluminumcable', 'id');
}
public function steelconduit()
{
return $this->hasOne('steelconduit', 'id');
}
}
See the error
Your error report is quite bad, but seems that your Ilumination model doesnt have an alllamps method.
You should attacth LampModels to your Ilumination model with a relationship, insted of doing what you doing, cause is a wrong approach.
I think you access somewhere ticket method which was created in Illumination Model that offset error encountered..
public function ticket()
{
return $this->hasMany('ticket');
}
if you want to access illumination->ticket, you must use this method with loop.
foreach(illumination->tickets as ticket) {
$field1 = ticket->field1;
}
If your still facing any issue than share your error log page here..

Eager loading on polymorphic relations

class Admin {
public function user()
{
return $this->morphOne('App\Models\User', 'humanable');
}
public function master()
{
return $this->hasOne('App\Models\Master');
}
}
class Master {
public function admin()
{
return $this->hasOne('App\Models\Admin');
}
}
class User {
public function humanable()
{
return $this->morphTo();
}
public function images()
{
return $this->hasOne('\App\Models\Image');
}
}
class Image {
public function user()
{
return $this->belongsTo('\App\Models\User');
}
}
Now if I dump this:
return \App\Models\Admin::where('id',1)->with(array('user.images','master'))->first();
I get the perfect result one master, one user and one image record.
But if I do this
return $user = \App\Models\User::where('id',1)->with(array('humanable','humanable.master'))->first();
I only get one Admin record, the query get * from masters doesn't even run.
Any idea what I'm doing wrong, I'm sure this is possible.
If I remember correctly Laravel has lots of pitfall. You can try to use the protected $with var in Admin model instead of query builder with function.
class Admin {
protected $with = ['master'];
public function user() {
return $this->morphOne('App\Models\User', 'humanable');
}
public function master() {
return $this->hasOne('App\Models\Master');
}
}
In query builder, only need to include humanable. Now you should see master inside the humanable object.
return $user = \App\Models\User::where('id',1)->with('humanable')->first();
Hope this help.

Categories