cannot retrieve Category model with related items - php

I have very strange error in my laravel website.
I try to retrieve Category model with related items, but looking at the error I see that laravel tries to retrieve items field from category model and of course it fails. But I am completely cannot understand why it happens, because I have the same code working well in other parts of my website.
routes/web.php
Route::name('gallery.')->prefix('gallery')->group(function () {
Route::get('/', 'GalleryController#index')->name('index');
Route::get('/{slug}', 'GalleryController#item')->name('item');
});
GalleryController
public function item($slug)
{
$category = $this->imageRepository->getCategoryWithPaginatedImages($slug, $perPage = 20);
return view('pages.gallery.item', compact('category'));
}
ImageRepository
namespace App\Repositories;
use Illuminate\Database\Eloquent\Collection;
use App\Models\ImageCategory as Model;
class ImageRepository extends CoreRepository
{
protected function getModelClass()
{
return Model::class;
}
public function getCategoryWithPaginatedImages($slug, $perPage = null)
{
$columns = ['id','title','slug','description','image','published','metatitle','metakey','metadesc'];
$result = $this
->startConditions()
->whereSlug($slug)
->select($columns)
->with('images:id,title,category_id,md,lg')
->firstOrFail()
->toArray();
$result = Arr::arrayToObject($result);
$result->items = collect($result->items)->mypaginate($perPage);
return $result;
}
}
Image
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
protected $guarded = [];
public function category() { return $this->belongsTo(ImageCategory::class); }
}
ImageCategory
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ImageCategory extends Model
{
protected $guarded = [];
public $timestamps = false;
public function images() { return $this->hasMany(ImageCategory::class, 'category_id'); }
}
so when I hit gallery/slug then getCategoryWithPaginatedImages gives me following error
Illuminate\Database\QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'category_id' in 'field list' (SQL: select `id`, `title`, `category_id`, `md`, `lg` from `image_categories` where `image_categories`.`category_id` in (2))

I guess the relationship images on ImageCategory definition has an issue, should be as under
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ImageCategory extends Model
{
protected $guarded = [];
public $timestamps = false;
public function images()
{
return $this->hasMany(Image::class, 'category_id');
}
}

Related

How can I get a pivot on my relationship in Laravel?

I have a relationship in my app. A candidate can have several "candidate_trainings" and each "candidate_training" is associated with a training. I wanted to avoid making "candidate_trainings" the piviot since it's hard to delete the right values when detaching, etc. So, how can I, on my hasMany relationship get the CandidateTraining model with the data from the Training model.
Here are my relationships:
<?php
namespace App;
use App\Traits\SanitizeIds;
use App\Salary;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Candidate extends Model
{
public function saveTraining($data) {
$this->candidateTrainings()->delete();
foreach(json_decode($data['training']) as $training) {
if(Training::find($training->training)->first()) {
$candidateTraining = new CandidateTraining;
$candidateTraining->description = $training->value;
$candidateTraining->training_id = $training->training;
$this->candidateTrainings()->save($candidateTraining);
}
}
}
public function candidateTrainings() {
return $this->hasMany('\App\CandidateTraining');
}
public function trainings() {
return $this->belongsToMany('\App\Training');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Training extends Model
{
protected $fillable = ['name_french', 'name_english'];
public function candidates() {
return $this->belongsToMany('\App\Candidate');
}
public function candidateTrainings() {
return $this->hasMany('\App\CandidateTraining');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class CandidateTraining extends Pivot
{
public function candidate() {
return $this->belongsTo('\App\Candidate');
}
public function training() {
return $this->belongsTo('\App\Training');
}
}
Thank you!
For you to be able to update the data directly on the CandidateTraining model, you need to add the $fillable fields to it.
protected $fillable = ['training_id', 'description'];
Your code should work! But if you don't mind, I did a little refactoring. You can accomplish this in another way:
<?php
namespace App;
use App\Traits\SanitizeIds;
use App\Salary;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Candidate extends Model
{
public function saveTraining($data)
{
// remove all relationships
$this->trainings()->detach();
// add new ones
foreach(json_decode($data['training']) as $training)
{
if(Training::find($training->training)->first())
{
$this->trainings()->attach($training->training, [
'description' => $training->value,
]);
}
}
}
public function candidateTrainings()
{
return $this->hasMany(App\CandidateTraining::class);
}
public function trainings()
{
return $this->belongsToMany(App\Training::class)
->withTimestamps()
->using(App\CandidateTraining::class)
->withPivot([
'id',
'training_id',
'description',
]);
}
}
That $training->training stuff is not readable, change it to something like $training->id if you are able to.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Training extends Model
{
protected $fillable = ['name_french', 'name_english'];
public function candidates()
{
return $this->belongsToMany(App\Candidate::class)
->withTimestamps()
->using(App\CandidateTraining::class)
->withPivot([
'id',
'training_id',
'description',
]);;
}
public function candidateTrainings()
{
return $this->hasMany(App\CandidateTraining::class);
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class CandidateTraining extends Pivot
{
protected $fillable = ['training_id', 'description'];
public function candidate()
{
return $this->belongsTo(App\Candidate::class);
}
public function training()
{
return $this->belongsTo(App\Training::class);
}
}
If you want to access the pivot object from a controller:
$candidates = Candidate::with(['trainings'])->get();
foreach ($candidates as $candidate)
{
dd($candidate->pivot);
}

Laravel Tables Join

I have three tables:
notes: id, business_id, note
businesses: id, title, description
businessimages : id, business_id, image
I get my customers notes with this:
$customer = Auth::guard('customer-api')->user();
$notes = Note::where('customer_id', $customer->id)->with('business:id')-
>orderBy('id', 'desc')->get();
Now I want to get notes.id, businesses.id, businesses.title, businesses.description, businessimages.image for each notes and show all of them in one json array
How could I do?
Note::where('customer_id',$customer->id)
->join('businesses', 'businesses.id', '=', 'notes.buisness_id')
->join('businessimages', 'businesses.id', '=', 'businessimages.buisness_id')
->select(notes.id, businesses.id, businesses.title, businesses.description,businessimages.image)
->get();
Note model;
public function business() {
return $this->hasOne('App\Business', 'business_id', 'id');
}
Business mode;
public function businessImage()
{
return $this->hasOne('App\BusinessImage', 'business_id', 'id');
}
Your controller;
$notes = Note::where('customer_id', $customer->id)->with('business.businessImage')->orderBy('id', 'desc')->get();
You should consider using API Resources
This is a great way to organize a model(or a collection of models as well).
App\Note
use Illuminate\Database\Eloquent\Model;
class Note extends Model
{
public function business()
{
return $this->belongsTo('App\Business');
}
}
App\Business
namespace App;
use Illuminate\Database\Eloquent\Model;
class Business extends Model
{
public function note()
{
return $this->hasOne('App\Note');
}
public function businessImage()
{
return $this->hasOne('App\BusinessImage');
}
}
App\BusinessImage
namespace App;
use Illuminate\Database\Eloquent\Model;
class BusinessImage extends Model
{
protected $table = 'businessimages';
public function business()
{
return $this->belongsTo('App\Business');
}
}
App\Http\Resources\Note
namespace App\Http\Resources;
class Note
{
public function toArray($request)
{
return [
'noteId' => $this->resource->id,
'businessId' => $this->resource->business->id,
'businessTitle' => $this->resource->business->title,
'businessDescription' => $this->resource->business->description,
'businessImage' => $this->resource->business->businessImage->image
];
}
}
Somewhere in a controller
use App\Http\Resources\Note as NoteResource;
public function foo()
{
$customer = Auth::guard('customer-api')->user();
$notes = Note::where('customer_id', $customer->id)->with(['business','business.businessImage'])->orderBy('id', 'desc')->get();
return NoteResource::collection($notes);
}

Laravel Eloquent: 3 table relationship

I'm new to Laravel-eloquent, I would like to translate this SQL to Eloquent mode:
select
fl.id, fut.id, fut.firebase_topic_id, ft.id, fl.created_at
from
firebase_logs fl,
firebase_user_topics fut,
firebase_topics ft
where
fl.id = fut.firebase_log_id
and
fut.firebase_topic_id = ft.id
and
fl.created_at between '2019-01-09 16:33:39' and '2019-01-09 16:33:41'
and
ft.id = 1
order by fl.created_at asc
Where:
Firebase_logs.id (1) -> Firebase_user_topics.firebase_log_id (N)
and
Firenase_user_topics.firebase_topic_id (N) -> Firebase_topics.id (1)
FirebaseLog.php:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class FirebaseLog extends Model
{
public $incrementing = false;
protected $primaryKey = 'id';
public function user_topics() {
//return $this->hasManyThrough(FirebaseTopics::class, FirebaseUserTopics::class);
return $this->hasMany(FirebaseUserTopics::class);
}
}
FirebaseUserTopics.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class FirebaseUserTopics extends Model
{
protected $table = 'firebase_user_topics';
public function log()
{
return $this->belongsTo(FirebaseLog::class);
}
public function topic()
{
return $this->belongsTo(FirebaseTopics::class);
}
}
FirebaseTopics.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class FirebaseTopics extends Model
{
protected $table = 'firebase_topics';
public function user_topics()
{
return $this->hasMany(FirebaseUserTopics, 'firebase_user_topics');
}
}
My Controller, works fine with this:
$a = FirebaseLog::with('user_topics')->whereBetween('created_at', array('2019-01-09 16:33:39', '2019-01-09 16:33:41'))->get();
return $a;
But I don't know how to connect to FirebaseTopics to continue building the code, some help will be appreciated.
EDITED ANSWER!
The solution of your problem is use the hasOne relation instead of belongsTo in your FirebaseUserTopics model. It must be following;
public function topic()
{
return $this->hasOne(FirebaseTopics::class, 'id', 'firebase_topic_id');
}
Because your FirebaseTopics model has not a relation with FirebaseUserTopics model. The "belongsTo" (that uses to make reverse a relation) search firebase_topic_id field in the firebase_topics table but this field has no in the firebase_topics table. That's why, you must be make to relation directly, not reverse.

Eloquent: Relationships

I have a big problem with the relation between two tables.
I want to link Subscription to Orders like this :
$subs = Subscription::first()->order->id
But nothing work i tried everything.
Subscription table :
Order table :
I tried this model but it don't work :
namespace App;
use Illuminate\Database\Eloquent\Model;
class Subscription extends Model
{
public $timestamps = false;
public function order()
{
return $this->hasOne('App\Order');
}
}
Order model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
public $timestamps = false;
public function payouts()
{
return $this->hasMany('App\Payout');
}
public function subscription()
{
return $this->belongsTo('App\Subscription');
}
}
error :
ErrorException: Trying to get property of non-object in /var/www/vhosts/trafficshield.tools/httpdocs/app/Http/Controllers/CampaignController.php:58
Line 58 : $order_id = Subscription::where('id', '=', 'GjhQpVSdQPirGmEEkJ6pGw')->first()->order->id;
Thank's for your
Because you are using a non autoincrement value as primary key you have to put this in your models:
public $incrementing = false;

Laravel 5.2 QueryException in Connection.php line 669

i'm developing an API but when I create the relations (Many to Many) and want to show in the index function I'm getting an error QueryException in Connection.php line 669 The error says:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'CTL_Tags.id' in 'on clause' (SQL: select `CTL_Tags`.*, `CTL_Resource_has_Tags`.`idResource` as `pivot_idResource`, `CTL_Resource_has_Tags`.`idTag` as `pivot_idTag` from `CTL_Tags` inner join `CTL_Resource_has_Tags` on `CTL_Tags`.`id` = `CTL_Resource_has_Tags`.`idTag` where `CTL_Resource_has_Tags`.`idResource` is null)
I believe my error is in my model because it's looking for id in CTL_Tags table when my id name in that table is idTag.
This is my CTL_Resource model
<?php
namespace Knotion;
use Illuminate\Database\Eloquent\Model;
class CTL_Resource extends Model {
public $timestamps = false;
protected $table = "CTL_Resource";
protected $hidden = [
'coachVisibility', 'thumbnail', 'tags', 'relatedTo',
'studentVisibility', 'isHTML','studentIndex', 'coachIndex',
'isURL', 'source', 'path', 'status', 'updateTime', 'isfolder',
'parentResource', 'idModifierUser'
];
protected $fillable = ['idResourceType','productionKey', 'tags', 'idCreatorUser', 'idModifierUser', 'idCreationCountry', 'title', 'description', 'URL', 'fileName', 'extension', 'quicktag', 'minimumAge', 'maximumAge', 'productionKey'];
public function creatorUser() {
return $this->belongsTo('Knotion\OPR_User', 'idCreatorUser');
}
public function creationCountry() {
return $this->belongsTo('Knotion\CTL_Country', 'idCreationCountry');
}
public function resourceType() {
return $this->belongsTo('Knotion\CTL_ResourceType', 'idResourceType');
}
public function quickTags() {
return $this->belongsToMany('Knotion\CTL_QuickTag', 'CTL_Resource_has_QuickTags', 'idResource', 'idQuickTag');
}
public function tags() {
return $this->belongsToMany('Knotion\CTL_Tag','CTL_Resource_has_Tags', 'idResource', 'idTag');
}
public function relatedTo() {
return $this->belongsToMany('Knotion\CTL_RelatedTo', 'CTL_Resource_has_RelatedTo', 'idResource', 'idRelatedTo');
}
}
and I just will show you the code of one of the relations
<?php
namespace Knotion;
use Illuminate\Database\Eloquent\Model;
class CTL_QuickTag extends Model {
protected $table = "CTL_QuickTags";
protected $fillable = ['name'];
protected $hidden = ['status', 'createTime', 'updateTime'];
public function resources() {
return $this->belongsToMany('Knotion\CTL_Resource', 'CTL_Resource_has_QuickTags', 'idResource', 'idQuickTag');
}
}
and this is my Controller
<?php
namespace Knotion\Http\Controllers;
use Illuminate\Http\Request;
use Knotion\Http\Requests;
use Knotion\Http\Requests\ResourcesRequest;
use Knotion\CTL_Resource;
use Knotion\CTL_Tag;
use Knotion\CTL_QuickTag;
use Knotion\CTL_RelatedTo;
use Knotion\CTL_ResourceType;
class ResourcesController extends Controller {
public function index(Request $request) {
$resources = CTL_Resource::paginate(10);
$resources->each(function($resources) {
$resources->tags;
$resources->quickTags;
$resources->relatedTo;
});
return response()->json(
$resources
);
I'll be so grateful who anyone can help me. Thank you so much.
Try to define
$primaryKey
in your model , with the correct column name
https://laravel.com/docs/5.2/eloquent#defining-models

Categories