I'm new to laravel and trying to understand correctly how to show in my view my picture of my relations.
For example I have a table for Category, Post, User, and Image, and I need some help with this.
For my DB it's OK with Image table like tutorial polymorphic relation on laravel docs.(same like doc)
In my models image I have my polymorphic relation and it's all OK
class Image extends \Eloquent {
protected $guarded = ['id' , 'created_at'];
public function imageable(){
return $this->morphTo();;
}
}
I need to associate a image on my different category
class Category extends \Eloquent {
protected $guarded = ['id' , 'created_at'];
public function posts(){
return $this->hasMany('Post');
}
public function images(){
return $this->morphMany('Image','imageable');
}
public function parent(){
return $this->belongsTo('Category','parent_id');
}
public function children(){
return $this->hasMany('Category','parent_id');
}
public function getImportantPost(){
return $this->hasOne('Post')->latest();
}
public function latestPost(){
return $this->hasOne('Post')->latest();
}
}
After that in my homecontroller for my home page I have a request for 1 particular post to show with a specific category
//show headliner post specific category
$headliner = Category::with(['posts' => function($query){
$query->orderBy('published_at', 'DESC')->take(1)->get();
}])->where('id' , '=' , '5')->get();
In my home index view I have a foreach $headliner like this
<div class="widget-area-4">
<div class="widget kopa-article-list-widget">
<ul class="clearfix">
#foreach($headliner as $headline)
<li>
<article class="entry-item clearfix">
<div class="entry-thumb">
<img src="{{$headline}}" alt="" />
<span class="category-title">{{$headline->name}}</span>
</div>
<!-- entry-thumb -->
<div class="entry-content">
<header>
<h5 class="entry-title">{{$headline->latestPost->name}}</h5>
<span class="entry-date"><i class="fa fa-calendar"></i> {{$headline->latestPost->published_at}}</span>
<span class="entry-categories">Auteur: </span>
<span class="entry-comments">{{$headline->latestPost->counts_comments}}<span></span></span>
</header>
<p>{{str_limit($headline->latestPost->content, 600 ,' ...' )}}</p>
<a class="more-link" href="#">Voir plus</a>
</div>
<!-- entry-content -->
</article>
<!-- entry-item -->
</li>
#endforeach
</ul>
</div>
<!-- kopa-article-list-widget -->
</div>
But I don't know how to show my image in my foreach because I have my post associated to category so it's OK but when I try to
{{$headline->images->path}}
(path is my entries in my DB) I have a error.
Thanks for your help.
As you've used morphMany() to define images relation for a category, loading this relation will give you a collection of Image objects. Therefore in your view $headline->images refers to this collection, not a single image. Collection does not have a path attribute, hence the error.
You'll need to iterate through your images collection in the view and then render each image separately, e.g.:
#foreach($headline->images as $image)
<img src="{{ $image->path }}" />
#endforeach
Related
So I'm currently practicing with Laravel, and running into a problem where the sql query is reading everything from my second table as an array, rather than the column it should be assigned to.
I have a packages table, and a resources table to fill those packages. Package name and price work fine, but when I need to read from resources, I get this:
[{"id":2,"resource":"Vegetarian menu","package_id":2,"created_at":"2022-06-18T19:34:48.000000Z","updated_at":"2022-06-18T19:34:48.000000Z"},{"id":3,"resource":"Standard Menu","package_id":2,"created_at":"2022-06-18T19:35:31.000000Z","updated_at":"2022-06-18T19:35:31.000000Z"}]
When it really should be just "Vegetarian menu", and "Standard Menu"
What am I doing wrong?
//package model
class Package extends Model { use HasFactory;
protected $fillable = ['name'];
public function resources()
{
return $this->hasMany(Resource::class);
} }
//package controller
class PackageController extends Controller {public function index(){
// SELECT * FROM packages
$packages = Package::with('resources')->get();
return view('service', compact('packages')); } }
//resource model
class Resource extends Model {
use HasFactory;
protected $fillable = ['package_id', 'resource'];
public function package()
{
return $this->belongsTo(Package::class);
} }
// UI Page
#foreach ($packages as $package)
<div class="tile is-parent"><!-- each child tile needs it's own parent -->
<article class="tile is-child box has-text-centered">
<figure class="image is-96x96 is-inline-block">
<img class="is-rounded" src="https://bulma.io/images/placeholders/96x96.png" alt="">
</figure>
<p class="subtitle has-text-centered">{{ $package->name }}</p>
<h4 class="is-size-5 has-text-centered">£{{ number_format($package->cost) }}.00</h4>
<div class="content">
<ul>
<li>{{ $package->resources }}</li>
</ul>
</div><!-- content -->
</article>
</div><!-- parent -->
#endforeach
You are correctly getting what you are requesting. A collection of resources associated with every package.
[
{
"id":2,
"resource":"Vegetarian menu",
"package_id":2,
"created_at":"2022-06-18T19:34:48.000000Z",
"updated_at":"2022-06-18T19:34:48.000000Z"
},
{
"id":3,
"resource":"Standard Menu",
"package_id":2,
"created_at":"2022-06-18T19:35:31.000000Z",
"updated_at":"2022-06-18T19:35:31.000000Z"
}
]
If you want to limit the fields on the resource relation then you should modify your query as
class PackageController extends Controller {
public function index(){
// SELECT * FROM packages eager loads resource name and package_id
$packages = Package::with('resources:resource,package_id')->get();
return view('service', compact('packages'));
}
}
you just need to loop through the related collection
#foreach ($packages as $package)
<div class="tile is-parent"><!-- each child tile needs it's own parent -->
<article class="tile is-child box has-text-centered">
<figure class="image is-96x96 is-inline-block">
<img class="is-rounded" src="https://bulma.io/images/placeholders/96x96.png" alt="">
</figure>
<p class="subtitle has-text-centered">{{ $package->name }}</p>
<h4 class="is-size-5 has-text-centered">£{{ number_format($package->cost) }}.00</h4>
<div class="content">
<ul>
#foreach ($package->resources as $r)
<li>{{ $r->resource }}</li>
#endforeach
</ul>
</div><!-- content -->
</article>
</div><!-- parent -->
#endforeach
I want to display all the products that have at least one image, then I display one of the image as the card's cover. But the query I made is displaying cards as many as images in the database.
Models
class Product extends Model {
public function getAllData()
{
$data = DB::table('product')
->select('product.*', 'product_images.img')
->join('product_images', 'product_images.product_id', '=', 'product.id')
->paginate(9);
return $data;
}
}
class ProductImage extends Model
{
public function product()
{
return $this->belongsTo(product::class);
}
}
Controller
public function index()
{
$img = ProductImage::find(1);
$data = [
'card' => $img->product->getAllData(),
];
return view('view', $data);
}
View
#foreach ($card as $item)
<div class="card shadow m-3" style="width: 18rem; heigth:24rem">
<div class="inner">
<img class="card-img-top" src="{{$item->img}}" alt="Card image cap">
</div>
<div class="card-body text-center">
<h5 class="card-title">{{$item->name}}</h5>
<p class="card-text">{{$item->description}}</p>
Check them out...
</div>
</div>
#endforeach
So I want to retrieve all Product instances with ProductImage instances in single array $card. What is the right way to do this?
Thanks in advance.
What I understand from you're requirement is you want to display all the products which have atleast 1 image against a product.
public function index()
{
$products = Product::has('image')
->with('image')
->get();
$data = [
'card' => $products,
];
return view('view', $data);
}
This will return all the products which has 1 image and the image can be used via image relation
#foreach ($card as $item)
<div class="card shadow m-3" style="width: 18rem; heigth:24rem">
<div class="inner">
<img class="card-img-top" src="{{$item->image->img}}" alt="Card image cap">
</div>
<div class="card-body text-center">
<h5 class="card-title">{{$item->name}}</h5>
<p class="card-text">{{$item->description}}</p>
Check them out...
</div>
</div>
#endforeach
Product Model
class Product extends Model
{
public function image()
{
return $this->hasOne(ProductImage:class);
}
public function images()
{
return $this->hasMany(ProductImage:class);
}
}
I have only used Laravel Eloquent, so the way I've shown the rendering of the products in view might be wrong
I am trying to get the posts that belong to each category, i had this working before but i can't seem to find what i have done wrong here.
I have a Post Table and a Categories Table
ROUTE
Route::get('articles/category/{id}', ['as' => 'post.category', 'uses' => 'ArticlesController#getPostCategory']);
CONTROLLER
public function getPostCategory($id)
{
$postCategories = PostCategory::with('posts')
->where('post_category_id', '=', $id)
->first();
$categories = PostCategory::all();
// return view
return view('categories.categoriesposts')->with('postCategories', $postCategories)->with('categories', $categories);
}
VIEW
#foreach($postCategories->posts as $post)
<div class="well">
<div class="media">
<a class="pull-left" href="#">
<img class="media-object" src="http://placekitten.com/150/150">
</a>
<div class="media-body">
<h4 class="media-heading">{{ substr($post->title, 0, 50) }}</h4>
<p class="text-right">By Francisco</p>
<p>{{ substr($post->body, 0, 90) }}</p>
<ul class="list-inline list-unstyled">
</ul>
</div>
</div>
</div>
#endforeach
POST MODAL
public function postCategory()
{
return $this->belongsTo('App\PostCategory');
}
POSTCATEGORY MODAL
class PostCategory extends Model
{
// connect Categories to Posts tables
protected $table = 'post_categories';
// Category belongs to more than 1 post
public function posts()
{
return $this->hasMany('App\Post', 'post_category_id');
}
}
I can't see what i am doing wrong every time I go to a category it shows
Trying to get property of non-object
Any help will be much appreciated thanks
replace your lines:
$postCategories = PostCategory::with('posts')
->where('post_category_id', '=', $id)
->first();
with:
$postCategories = PostCategory::find($id)->posts;
Change your line in your PostCategoryModel to:
return $this->hasMany('App\Post', 'post_category_id','post_category_id');
I asked this question before but didnt get any answer,hope you have the solution.
As I have 2 tables, items and categories so every item has one category and one category can have many items.
my problem is when using groupby function but it shows one item for every category
item model:
class Item extends Model
{
protected $table="items";
protected $fillable=
['item_title','category_id','item_price','item_details','item_image'];
protected $primaryKey='item_id';
public $timestamps=false;
public function categories()
{
$this->hasOne('App\category','category_id','category_id');
}
}
category model
class Category extends Model
{
protected $table="categories";
protected $fillable=['category_name'];
protected $primaryKey='category_id';
public $timestamps=false;
public function items()
{
$this->hasMany('App\items','category_id','category_id');
}
}
Controller
class HomeController extends Controller
{
public function getItems()
{
$items = Item::groupBy('category_id')->get();
return view('home',compact('items'));
}
}
HTML
#foreach($items as $indexKey => $item)
<div class="MenuPage_contentArea">
<div class="Category_root" id="one">
<div class="Category_categoryHeader">
<div><h2 class="Category_name">{{$item->item_category}}</h2></div>
<div class="Category_description"></div>
</div>
<div class="Category_itemsContainer">
<div class="Category_itemContainer">
<button class="Item_root Button_root">
<div class="Item_image" style="background-image: url('{{ asset('images/' . $item->item_image) }}');"></div>
<div class="Item_itemContent">
<div class="Item_topSection">
<span class="Item_name">{{$item->item_title}}</span>
<span class="Item_price">${{$item->item_price}}</span></div>
<div class="Item_description">{{$item->item_details}}</div>
</div>
</button>
</div>
</div>
</div>
</div>
#endforeach
You are grouping at SQL level, but if you want all of the items in a category grouped in a Collection, then use groupBy method from Collection. Use all()
method to get a collection of all items, then use groupBy() method to group the items by category_id:
HOME CONTROLLER
class HomeController extends Controller
{
public function getItems()
{
$items = Item::all()->groupBy('category_id');
return view('home',compact('items'));
}
}
Access in your blade File as:
#foreach($items as $category_id => $categoryItems)
Category ID: {{ $category_id }} <br>
#foreach($categoryItems as $item)
<!-- Display Item Details Here -->
#endforeach
#endforeach
Hope it helps you. :)
My model code
how we can call this function in blade.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BasicModel extends Model
{
public static function get_product_count($id){
$query = "select COUNT(sub_id) AS count FROM products WHERE products.sub_id = $id";
print_r($query);
return $query->row_array();
}
}
My view.blade.php code
count in foreach loop or show in all category
#foreach ($r as $row)
<li class="grid-item type-rent">
<div class="property-block">
<img src="{{ URL::to('/template/images/background-images/sub-category-images/' .$row->sub_cat_images. '')}}" alt=""> <!-- <span class="images-count"><i class="fa fa-picture-o"></i> 2</span> <span class="badges">Rent</span> -->
<div class="property-info">
<h4>{{ ucwords(substr($row->sub_cat_name, 0, 22)) }}</h4>
<span class="location">NYC</span>
<div class="price"><strong>Items</strong><span>
<!-- start count code from here -->
$data = $this->BasicModel->count {{ ($row->sub_id) }}
echo $data['count'];
</span></div>
</div>
<!-- <div class="property-amenities clearfix"> <span class="area"><strong>5000</strong>Area</span> <span class="baths"><strong>3</strong>Baths</span> <span class="beds"><strong>3</strong>Beds</span> <span class="parking"><strong>1</strong>Parking</span> </div> -->
</div>
</li>
#endforeach
My BasicController Code
public function grid(Request $request, $id)
{
if ($id == 1) {
$r = DB::table('sub_category')->select('*')->where('cat_id', $id)
->where('sub_status', '1')->orderBy('sub_id', 'asc')->get();
$name = DB::table('category')->where('cat_id', $id)->get();
return view('buy-and-sell/grid', compact('r','name','count'));
}
image for your help
image for your help
problem in this image please solve the problem
Although its no good Practice Accessing the DB in Blade (better do this in the controller and pass the data) you can do:
<div class="price"><strong>Products</strong>
<span>
{{ BasicModel::where('sub_id', $row->sub_id)->count() }}
</span>
</div>
Its not tested, but have a look at the Eloquent docs, the count() method is explained there.
Update: I am not shure if laravel will find the class BasicModel (I never would access Models directly in blade, as stated do this in the controller and pass the data.) So maybe you need to write it with the full Namespace most likely {{ \App\BasicModel::where() }}.