I have a business table which is linked using eloquent with table addresses, location and gallery.
Output looks like this:
Collection {#266 ▼
#items: array:1 [▼
0 => Business {#260 ▼
#table: "businesses"
+timestamps: true
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:14 [▶]
#original: array:14 [▶]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: array:3 [▼
"addresses" => Collection {#261 ▼
#items: array:1 [▼
0 => Address {#263 ▼
#table: "addresses"
+timestamps: true
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:9 [▼
"id" => 10
"firstline_address" => "96"
"secondline_address" => "Cambridge Street"
"town" => "p.wojtas26#gmail.com"
"city" => "p.wojtas26#gmail.com"
"postcode" => "SK15 1AU"
"telephone" => "7815522481"
"created_at" => "2017-06-26 08:05:32"
"updated_at" => "2017-06-26 08:05:32"
]
#original: array:11 [▶]
#casts: []
#dates: []
#dateFormat: null
#appends: []
#events: []
#observables: []
#relations: array:1 [▼
"pivot" => Pivot {#262 ▶}
]
#touches: []
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
]
}
"location" => Location {#279 ▶}
"gallery" => null
]
However the problem is that is says:
Property [addresses] does not exist on this collection instance. (View: C:\xampp\htdocs\laravel\resources\views\displayBusiness.blade.php)
here's my view:
#foreach($business->addresses as $address)
<p>{{$address->firstline_address}}</p>
<p>{{$address->secondline_address}}</p>
<p>{{$address->town}}</p>
<p>{{$address->city}}</p>
<p>{{$address->postcode}}</p>
<p>{{$address->telephone}}</p>
#endforeach
</div>
Model:
class Business extends Model
{
protected $table = 'businesses';
public $timestamps = true;
use Searchable;
public function addresses()
{
return $this->belongsToMany('App\Address', 'business_address', 'business_id', 'address_id');
}
public function gallery()
{
return $this->hasOne('App\Gallery', 'business_id');
}
public function film()
{
return $this->hasOne('App\Film', 'business_id');
}
public function location()
{
return $this->hasOne('App\Location', 'business_id');
}
public function user()
{
return $this->hasMany('App\User', 'user_business', 'business_id', 'user_id');
}
Another problem is that sometimes a field is empty so let's say sometimes $address->city = null how would I tell to ignore that field and carry on?
I can do #if($address->city == NULL) but I don't want to do it for each one as I cannot predict what will be empty.
//edit
Controller:
public function displayBusiness($id) {
$business = Business::where('id', $id)
->with('addresses')
->with('location')
->with('gallery')
->get();
//dd($business);
/*
$instagram = $business->instagram_business;
$twitter = $business->twitter_business;
$instagramItems=[];
$twitterItems=[];
if(!empty ($instagram)){
$client = new \GuzzleHttp\Client();
$url = sprintf('https://www.instagram.com/'.$instagram.'/media');
$response = $client->get($url);
$instagramItems = json_decode((string) $response->getBody(), true)['items'];
$twitterItems = Twitter::getUserTimeline(['screen_name' => $twitter, 'count' => 10, 'format' => 'array']);
*/
//$session = session()->put('key', $id);
//$gallery = Gallery::where('business_id', $id)->get();
//$location = Location::where('business_id', $id)->get();
//$review = Review::where('business_id', $id)->get();
return view('business.displayBusiness', compact('business', 'address', 'gallery', 'location', 'review', 'instagramItems', 'twitterItems'));
/*}
//edit2
It now says
Trying to get property of non-object (View: C:\xampp\htdocs\laravel\resources\views\business\displayBusiness.blade.php)
Which is:
#foreach ($business->location as $marker)
<script>
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 19,
center: {lat: {{$marker->latitude}}, lng: {{$marker->longitude}}}
});
It looks like you need to change
$business = Business::where('id', $id)
->with('addresses')
->with('location')
->with('gallery')
->get();
to
$business = Business::where('id', $id)
->with('addresses')
->with('location')
->with('gallery')
->first();
Your problem is that your query is returning a Collection rather than a single instance of Business, this is because your query is searching for multiple businesses and will generate a Collection of any businesses it finds, even if there is just one.
Better to use has()
$business = Business::where('id', $id)
->has('addresses')
->has('location')
->has('gallery')
->get();
Querying Relationship Existence
https://laravel.com/docs/5.7/eloquent-relationships#querying-relations
Related
I am using the following trait to generate UUID's for my user model. I have setup a listener to the following event: Illuminate\Auth\Events\Login. This works when you just normally sign-in to the app (using Laravel Breeze). But when I manually do auth()->user($user) I get back an instance of Illuminate\Foundation\Auth\User where the keyType is an integer and incrementing is set to true, although my trait does otherwise.
Anyone knows how to fix this?
<?php
namespace App\Traits;
use Ramsey\Uuid\Uuid;
trait Uuidable
{
/**
* Cast the primary key type as a string
*/
public function initializeUuidable()
{
$this->setKeyType('string');
}
/**
* Set the model to none incrementing
*
* #return bool
*/
public function getIncrementing()
{
return false;
}
/**
* Set the key of the model
*
* #return void
*/
public static function bootUuidable()
{
static::creating(function ($model) {
if (!isset($model->attributes[$model->getKeyName()])) {
$model->incrementing = false;
$uuid = Uuid::uuid4();
$model->attributes[$model->getKeyName()] = $uuid->toString();
}
}, 0);
}
}
Illuminate\Foundation\Auth\User {#1494 ▼
#connection: "mysql"
#table: "users"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:13 [▶
"id" => "31f12e1a-964c-4580-8a20-263c8bb7bf95"
"first_name" => "test"
"last_name" => "user"
"email" => "test#mrpackage.com"
"email_verified_at" => null
"password" => "$2y$10$vTAYxvC4s95PpF5BmzC0p..ZiQfcn3WARxXalgmd1kVZn5X1S/F02"
"last_login_id" => null
"remember_token" => null
"welcome_valid_until" => null
"printer_id" => null
"created_at" => "2021-09-15 14:38:00"
"updated_at" => "2021-09-15 14:38:20"
"deleted_at" => null
]
#original: array:13 [▶
"id" => "31f12e1a-964c-4580-8a20-263c8bb7bf95"
"first_name" => "test"
"last_name" => "user"
"email" => "test#mrpackage.com"
"email_verified_at" => null
"password" => "$2y$10$vTAYxvC4s95PpF5BmzC0p..ZiQfcn3WARxXalgmd1kVZn5X1S/F02"
"last_login_id" => null
"remember_token" => null
"welcome_valid_until" => null
"printer_id" => null
"created_at" => "2021-09-15 14:38:00"
"updated_at" => "2021-09-15 14:38:20"
"deleted_at" => null
]
#changes: array:3 [▶
"password" => "$2y$10$vTAYxvC4s95PpF5BmzC0p..ZiQfcn3WARxXalgmd1kVZn5X1S/F02"
"welcome_valid_until" => null
"updated_at" => "2021-09-15 14:38:20"
]
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶
0 => "*"
]
#rememberTokenName: "remember_token"
}
Today I'm facing some very weird behavior in Laravel while fetching records from the table. I'm having a table which has One to Many Relation with itself. A Menu item can have multiple Submenu. Below is a brief structure:
Table name: site_navigation
id => Primary Key, Auto Increment
parent_id => Index, Defaults Null
menu_name => Varchar
Model => 'Sitemenu_model.php'
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class Sitemenu_model extends Model
{
protected $table = 'site_navigation';
public function getParent()
{
return $this->belongsTo('App\Models\backend\Sitemenu_model', 'parent_id');
}
public function getChildren()
{
return $this->hasMany('App\Models\backend\Sitemenu_model', 'parent_id');
}
}
Controller => 'Pagescontent.php'
use App\Models\backend\Sitemenu_model;
class Pagescontent extends Controller
{
$collSiteMenu = Sitemenu_model::with('getChildren')
->orderBy('display_order', 'asc')
->get();
return view('backend.pages.pagescontent.create', ['collSiteMenu'=>$collSiteMenu]);
}
View => 'create.blade.php'
#foreach($collSiteMenu as $menu)
#php
$arrMainMenu[$menu->id] = $menu->menu_name;
#endphp
#endforeach
The '$arrMainMenu' is only having the last record of the collection. When i tried to print $menu->id, it prints blank. Even the child record doesn't print its menu id. Even if i use below code, still no output. Which means 'id' attribute is not set.
#foreach($collSiteMenu as $menu)
#isset($menu->id)
{{ 'menu id is set to '. $menu->id }}
#endisset
#endforeach
However, in controller, when i dd($collSiteMenu) it prints below:
Collection {#380 ▼
#items: array:12 [▼
0 => Sitemenu_model {#393 ▼
#table: "site_navigation"
#fillable: array:10 [▶]
+id: null
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:13 [▼
"id" => 1
"menu_name" => "About Us"
"parent_id" => null
"url_slug" => "about-us"
"canonical_url" => null
"show_in_nav" => "show_both"
"meta_title" => "About Us"
"meta_keywords" => null
"meta_description" => "this is test description"
"is_active" => "yes"
"display_order" => 1
"created_at" => "2020-09-02 12:39:20"
"updated_at" => "2020-09-04 16:21:51"
]
#original: array:13 [▼
"id" => 1
"menu_name" => "About Us"
"parent_id" => null
"url_slug" => "about-us"
"canonical_url" => null
"show_in_nav" => "show_both"
"meta_title" => "About Us"
"meta_keywords" => null
"meta_description" => "this is test description"
"is_active" => "yes"
"display_order" => 1
"created_at" => "2020-09-02 12:39:20"
"updated_at" => "2020-09-04 16:21:51"
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"getChildren" => Collection {#411 ▼
#items: array:2 [▼
0 => Sitemenu_model {#415 ▼
#table: "site_navigation"
#fillable: array:10 [▶]
+id: null
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:13 [▶]
#original: array:13 [▼
"id" => 7
"menu_name" => "Who We Are"
"parent_id" => 1
"url_slug" => "who-we-are"
"canonical_url" => null
"show_in_nav" => null
"meta_title" => "Who We Are"
"meta_keywords" => null
"meta_description" => null
"is_active" => "yes"
"display_order" => 1
"created_at" => "2020-09-02 14:14:03"
"updated_at" => "2020-09-02 14:14:03"
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => Sitemenu_model {#416 ▼
#table: "site_navigation"
#fillable: array:10 [▶]
+id: null
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:13 [▶]
#original: array:13 [▼
"id" => 8
"menu_name" => "Our Cause"
"parent_id" => 1
"url_slug" => "our-cause"
"canonical_url" => null
"show_in_nav" => null
"meta_title" => "Our Cause"
"meta_keywords" => null
"meta_description" => null
"is_active" => "yes"
"display_order" => 2
"created_at" => "2020-09-02 14:15:27"
"updated_at" => "2020-09-02 14:15:27"
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
I have searched on Google but couldn't find a solution to this. Can any one guide me as where I'm going wrong.
Much Regards,
Javed
Laravel framework 6.9 + XAMP
I need advise from someone with experience in Laravel as I have some strange issue I cannot explain.
Blade template has a button that should add an item to the cart via product id:
<div class="buy d-flex justify-content-between align-items-center">
<div class="price text-success"><h5 class="mt-4">$ {{$product->price}}</h5></div>
<i class="fas fa-shopping-cart"></i> Add to Cart
</div>
However nothing happens when the button is clicked. No product id is passed, just #.
This is web.php route that I call:
Route::get('add-to-cart/{id}', [
'uses' => 'ProductController#getAddToCart',
'as' => 'product.addToCart'
]);
Also tried:
//Route::get('add-to-cart/{id}', 'ProductController#getAddToCart')->name('product.addToCart');
Which also doesn't work.
This is Cart model:
<?php
namespace App;
class Cart
{
public $items = null;
public $totalQty = 0;
public $totalPrice = 0;
public function __construct($oldCart)
{
if ($oldCart) {
$this->items = $oldCart->items;
$this->totalQty = $oldCart->totalQty;
$this->totalPrice = $oldCart->totalPrice;
}
}
public function add($item, $id) {
$storedItem = ['qty' => 0, 'price' => $item->price, 'item'=> $item];
if ($this->items) {
if (array_key_exists($id, $this->items)) {
$storedItem = $this->items[$id];
}
}
$storedItem['qty']++;
$storedItem['price'] = $item->price * $storedItem['qty'];
$this->items[$id] = $storedItem;
$this->totalQty++;
$this->totalPrice += $item->price;
}
}
This is Product controller:
namespace App\Http\Controllers;
use App\Product;
use Illuminate\Http\Request;
use App\Cart;
use Session;
class ProductController extends Controller
{
public function index()
{
$products = Product::all();
return view('shop.index', ['products' => $products]);
}
public function getAddToCart(Request $request, $id) {
$product = Product::find($id);
$oldCart = Session::has('cart') ? Session::get('cart') : null;
$cart = new Cart($oldCart);
$cart->add($product, $product->id);
$request->session()->put('cart', $cart);
//dd($request->session()->get('cart'));
return redirect()->route('index');
}
}
If I just pass in URL: /add-to-cart/{prod id} and Enter, it works - I get to see dd() of the 'cart' with the product details, so the route works. Only the button doesn't!
Drives me nuts. What am I doing wrong? Is there some 'feature' in Laravel I don't know about?
dd($product)
App\Product {#279 ▼
#fillable: array:3 [▼
0 => "title"
1 => "description"
2 => "price"
]
#connection: "mysql"
#table: "products"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:7 [▼
"id" => 2
"created_at" => "2019-12-22 18:05:40"
"updated_at" => "2019-12-22 18:05:40"
"imagePath" => "https://s3.eu-central-1.amazonaws.com/bootstrapbaymisc/blog/24_days_bootstrap/vans.png"
"title" => "Neque quia sit facere."
"description" => "Seven flung down his cheeks, he went on growing, and, as the door opened inwards, and Alice's elbow was pressed hard against it, that attempt proved a failure. ▶"
"price" => 29
]
#original: array:7 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
The cart gets filled with product.
From what I'm seeing it seems that your route is not redirecting correctly. In your controller, the actions is defined as
public function getAddToCart(Request $request, $id)
but in your button you are only passing the id parameter.
Try redefining your method in your controller to
public function getAddToCart($id)
that should do the trick.
In my model, i have the following fillable array:
protected $fillable = [
'first_name',
'last_name',
'email',
'street',
'house_number',
'province',
'phone',
'country',
'date_of_birth',
'postcode',
'account_id',
'user_id'
];
user_id is nullable and account_id is not.
When i try to create a new entity, user_id stays null in my database.
This is my code for saving the entity:
#in controller
$this->dispatch(new Job($user = $request->user(), $client = new Client(),
$request->only($client->getFillable())
));
#in job class
$client = $this->client->create(array_merge([
'user_id ' => $this->user->id,
'account_id' => $this->user->account->id
],$this->variables));
This is all of the data going into the create method:
"user_id " => 3
"account_id" => 3
"first_name" => "patrick"
"last_name" => "vd pols"
"email" => "patrickvanderpolssad22dxsxs#live.nl"
"street" => "Dijkgraaf 2"
"house_number" => "asdasd"
"province" => "Drenthe"
"country" => "asdasdsad"
"date_of_birth" => "14-12-2019"
"postcode" => "3155GA"
Both user with ID 3 and account with ID 3 exist in my database.
After saving the entity, the user_id is null:
App\Client {#384 ▼
#fillable: array:12 [▶]
#connection: "mysql"
#table: "clients"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: true
#attributes: array:13 [▼
"account_id" => 3
"first_name" => "patrick"
"last_name" => "vd pols"
"email" => "patrickvanderpolssad22dxsxs#live.nl"
"street" => "Dijkgraaf 2"
"house_number" => "asdasd"
"province" => "Drenthe"
"country" => "asdasdsad"
"date_of_birth" => Carbon\Carbon #1576281600 {#385 ▶}
"postcode" => "3155GA"
"updated_at" => "2019-12-14 00:10:03"
"created_at" => "2019-12-14 00:10:03"
"id" => 8
]
#original: array:13 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
What am i not seeing?
Thanks!
Edit:
I am an idiot.
There was an extra space after user_id:
'user_id ' => $this->user->id
Solved.
You did find the catch!
But since you want me to write the answer, I gladly do it.
You had an extra space on your key 'user_id ' => $this->user->id
I query a model 'Royalty' and eager load the relationship 'Owner'. The model returns the result, including the relationship.
class Royalty extends Model
{
protected $guarded = [];
protected $dates = ['created_at', 'updated_at', 'date', 'calculated_at'];
protected $casts = [
'properties' => 'object',
];
public function owner()
{
return $this->belongsTo(Owner::class);
}
}
class Owner extends Model
{
use SoftDeletes;
protected $guarded = [];
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
protected $casts = [
'properties' => 'object',
];
public function royalties()
{
return $this->hasMany(Royalty::class);
}
}
$royalty = Royalty::with('owner')->where('id', 1)->first();
The result is as expected and the relationship 'owner' is eagerloaded:
Royalty {#542 ▼
#guarded: []
#dates: array:4 [▶]
#casts: array:1 [▶]
#connection: "development"
#table: "royalties"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:21 [▶]
#original: array:21 [▶]
#changes: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▼
"owner" => Owner {#562 ▼
#guarded: []
#dates: array:4 [▶]
#casts: array:1 [▶]
#connection: "development"
#table: "owners"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:8 [▶]
#original: array:8 [▶]
#changes: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#forceDeleting: false
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
}
However, when I call the relationship with $royalty->owner the result is NULL. What am I doing wrong here?
dd($royalty->owner); NULL
There are two main reason why this would happen.
one is that the information in the database has changer
You have overloaded the toArray() method in the model Owner (i know it's not in your example)
You must use fillable instead of guarded.
class Royalty extends Model
{
protected $fillable = [ 'id', ...];
protected $dates = ['created_at', 'updated_at', 'date', 'calculated_at'];
protected $casts = [
'properties' => 'object',
];
public function owner()
{
return $this->belongsTo(Owner::class);
}
}
You have to define your relatioship like this,
In royalty model please define
public function owner()
{
return $this->belongsTo(Owner::class,'owner_id');
} and take id as fillable in owner model.
And your
public function royalties()
{
return $this->hasMany(Royalty::class);
} is perfect