Many to many relation with fk in the pivot table - laravel

i have the following structure:
Database
ingredients
id,
name
products
id,
name
ingredient_product
ingredient_id,
product_id,
ingredient_type_id
ingredient_types
id,
name
Models
Product Model
class Product extends Model
{
public function ingredients() {
return $this->belongsToMany(Ingredient::class)
->withPivot('ingredient_type_id');
}
}
Ingredient Model
class Ingredient extends Model
{
public function products() {
return $this->belongsToMany(Product::class)
->withPivot('ingredient_type_id');
}
}
My SearchController
class SearchController extends Controller
{
public function search(InitialSearchRequest $request)
{
$productsResults = Product::where('name', 'LIKE', '%' . $request['initial-search'] . '%')
->with('ingredients', 'brand')
->get();
return view('search.index')
->with(compact('productsResults'))
->with('initial-search', $request['initial-search']);
}
}
And finally my View
<div class="card-group">
#foreach($productsResults as $product)
<div class="col-sm-6 col-md-4 col-lg-4">
<div class="card"><img class="card-img-top" src="..." alt="Imagem do produto" style="width: 100%; height:100px; background-color: #696969;">
<div class="card-body">
<h5 class="card-title">{{ $product->name }}</h5>
<p class="card-text">
Important Ingredients: <br>
#foreach($product->ingredients as $ingredient)
**{{ I need here the ingredient type }}** - {{ $ingredient->name }}
#endforeach
</p>
</div>
</div>
</div>
#endforeach
</div>
So i need to show in the view my products, with the ingredients and the type of each ingredient.
This approach isnĀ“t working......
I need help to finish this task.
Thank you for any help.

You can use a pivot model:
class IngredientProductPivot extends \Illuminate\Database\Eloquent\Relations\Pivot
{
public function ingredientType() {
return $this->belongsTo(IngredientType::class);
}
}
class Product extends Model
{
public function ingredients() {
return $this->belongsToMany(Ingredient::class)
->withPivot('ingredient_type_id')
->using(IngredientProductPivot::class);
}
}
Then access it like this:
{{ $ingredient->pivot->ingredientType->name }}
As far as I know, there is no way to eager load the type relation.

Related

Get objects of related tables from a collection laravel

I want to pass the result of a searching action but I am facing a problem because it is returning an array and from that all the relationships of the table are not working
result view. For this I can only access the data on my table not the related data through relationships
#extends('layouts.app')
#section('content')
#foreach ($result as $object)
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3>Details for the animal</h3>
</div>
<div class="card-body">
<div class="col-12">
<p><strong>Id: </strong>{{ $object->id }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
#endforeach
#endsection
Here is my controller
<?php
namespace App\Http\Controllers;
use App\Animal;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class SearchController extends Controller
{
public function index()
{
Animal::all();
return view('search.index');
}
public function postSearch(Request $request)
{
$serial_number = $request->input('search');
$this->getResult($serial_number);
return redirect()->route('result',$serial_number);
}
public function getResult($serial_number){
$result = DB::table('slaughters')->where(function ($query) use ($serial_number) {
$query->where('id','LIKE',"%$serial_number%");
})->latest()->get();
return view('search.result', ['result'=>$result]);
}
}
And my routes
Route::get('/search','SearchController#index')->name('search');
Route::post('/get','SearchController#postSearch');
Route::get('/search/{result}','SearchController#getResult')->name('result');
I would like to access data from the table related to this one too. What am to do
Slaughter model
class Slaughter extends Model
{
protected $guarded = [];
public function user(){
return $this->belongsTo(User::class);
}
public function animal(){
return $this->belongsTo(Animal::class);
}
You must create model Slaughter and define relations.
And then you can get result:
public function getResult($serial_number)
{
$result = Slaughter::with(['name_of_relation_1', 'name_of_relation_2'])->latest()->get();
return view('search.result', ['result'=>$result]);
}
In your Controller:
use App\Slaughter;
public function getResult($serial_number) {
$result = Slaughter::where('id', 'like', "%{$serial_number}%")
->with('user', 'animal')
->latest()
->get();
return view('search.result', compact('result'));
}
In your view you can then access the relationships like so:
{{ $object->user }}
{{ $object->animal }}

how to get single category and its subcategories in laravel blade

I have a code, where I am getting all the categories and its subcategories from the table, but i want to get a single category and it's subcategories from the categories table display in the laravel blade navigation file.
For example, I have shoes and shirts categories and their subcategories in the table, I want to display only shirts category and its subcategories show in the front end. please help me to achieve this.
I am getting all the categories and its subcategories from the table
Route:
//here i have added route url for link and well to display categories
Route::get('/products/{url}', 'ProductController#products');
Controller Method:
//this is function/method
public function products($url = null)
{
$countCategory = Category::where(['url'=>$url, 'status'=>1])->count();
if($countCategory==0){
abort(404);
}
//Get All Categories and Sub Categories
$categories = Category::with('categories')->where(['parent_id' => 0])->get();
$categoryDetails = Category::where(['url' => $url])->first();
if ($categoryDetails->parent_id==0) {
//if url is main category url
$sub_categories = Category::where(['parent_id'=>$categoryDetails->id])->get();
foreach ($sub_categories as $sub_cat) {
$cat_ids[] = $sub_cat->id;
}
// echo $cat_ids; die;
$productsAll = Product::whereIn('category_id',$cat_ids)->where('status', 1)->get();
} else {
$productsAll = Product::where(['category_id' => $categoryDetails->id])->where('status', 1)->get();
}
return view('products.listing')->with(compact('categories', 'categoryDetails', 'productsAll'));
}
Category Model:
public function categories()
{
return $this->hasMany('App\Category', 'parent_id');
}
Balde (View) file:
<div class="side-bar col-md-12">
<h3 class="agileits-sear-head">Category</h3>
<div class="panel-group" id="accordian">
{{-- this is the basic way to show the categores inthe table --}}
<?php //echo $categories_menu ?>
#foreach ($categories as $cat)
#if($cat->status=="1")
<div class="panel-heading" >
<h4 class="panel-title">
<a href="#{{ $cat->id }}" data-toggle="collapse" data-parent="#accordian">
<span class="badge pull-right"><i class="fa fa-plus"></i></span>
{{ $cat->name }}
</a>
</h4>
</div>
<div id="{{ $cat->id }}" class="panel-collapse collapse">
<div class="panel-body" >
<ul style="list-style: none; margin-left:30px;">
#foreach ($cat->categories as $sub_cat)
#if($sub_cat->status=="1")
<li>{{ $sub_cat->name }}</li>
#endif
#endforeach
</ul>
</div>
</div>
#endif
#endforeach
</div>
</div>
I appreciate the solution as earlier as possible
sir, I have a question that, I do not want to display my all categories in the sidebar, instead of I want only one category like shoe category and its subcategory I want to display, please guide me how to achieve this. and also i want different category sidebar for different categories,
example,
let's assume we have a shirts listing page where all the shirts, T-shirts and many more shirts related to Shirts Category only.
and i want only Shirts and its subcategory to display in the sidebar.
if i have shoes category and i want to display only shoes category and its subcategory in the sidebar.
please guide me how to achieve this sir,
It is very simple hasMany-belongsTo relationship, let me show you.
<?php
namespace App\models;
use App\pivotes\Catagory;
use Illuminate\Database\Eloquent\Model;
class Catagory extends Model
{
public function children()
{
return $this->hasMany(SELF::class, 'parent_id');
}
public function parentCategory()
{
return $this->hasMany(SELF::class, 'id', 'parent_id');
}
}
Migration file will be
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('category');
$table->unsignedInteger('parent_id')->nullable();
$table->timestamps();
$table->foreign('parent_id')->references('id')->on('comments');
});
for /categories/{category}
Controller method will be
CategoryController extends Controller {
public function show(Category $category)
{
return view('categories.show', $category);
}
}
In view
#foreach( $category->children as $subCategory )
{{ $subcategory->category }}
#endforeach

Get the user name and comment with article id in Laravel

I have 3 tables users, comments, and articles. I have a route like this:
Route::get('/article/{id}', 'ArticlesController#view');
What I want is when I accessing that route I will get User Name and their comment in this article id.
so here's my view function in ArticlesController:
public function view($id){
$article = Article::with('comments')->find($id);
return view('front.single',compact('article'));
}
and here's my single.blade.php code:
<div class="single-grid">
#section('content')
<h1>{{ $article->title }}</h1>
<p>{{ $article->content }}</p>
#show
</div>
<div class="comment-list">
#foreach($article->comments as $comment)
<ul class="comment-list">
<div class="comment-grid">
<img src="/images/avatar.png" alt=""/>
<div class="comment-info">
<h4>{{ $comment->user->name }}</h4>
<p>{{ $comment->comment }}</p>
<h5>{{ $comment->created_at->diffForHumans() }}</h5>
Reply
</div>
<div class="clearfix"></div>
</div>
</ul>
#endforeach
</div>
I'm not sure what how to do it since it gives me error like this:
"Call to undefined relationship [comment] on model [App\User]."
I already define the relation in each model. here's my articles model:
public function comments(){
return $this->hasMany(Comment::class);
}
public function user(){
return $this->belongsTo(User::class);
}
My comment model:
public function article(){
$this->belongsTo(Article::class);
}
public function user(){
$this->belongsTo(User::class);
}
and here's my User model:
public function articles(){
return $this->hasMany(Article::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function publish(Article $article){
$this->articles()->save($article);
}
here's my table structure:
-users(id,name,email,password,remember_token,created_at,updated_at)
-comments(id,user_id,article_id,comment,created_at,updated_at)
-articles(id,user_id,title,content,created_at,updated_at)
so how can I can User Name just by using this route? thanks.
on Your Comment Model, You need to replace articles to article
public function article(){
$this->belongsTo(Article::class);
}
also, if you want to get user specific comments, than you need to change your controller action code from
$article = Article::with('user.comment')->find($id) to
$article = Article::with('user.comments')->find($id);
I think that your issue comes from the use of compact function : an array is passed to the view instead of an object.
Can you try it like this :
// Controller
public function view($id) {
$article = Article::findOrFail($id);
return view('front.single', $article);
}
<!-- View -->
#foreach($article->comments as $comment)
{{ $comment->user->name }}
{{ $comment->comment }}
{{ $comment->created_at->diffForHumans() }}
#endforeach

get category name in a post record

I have a list containing article posts from all categories. I want to display the category tag in each post on the list and I tried this :
<article class="post bg z-depth-1">
<?php foreach ($article_list as $article): ?>
<div class="post-img">
<a href="post.html">
<img class="retina" src="{{ asset('image/' . $article->image) }}" width="820" height="500" alt="Post Image">
</a>
</div>
<div class="post-content">
<div class="post-header center-align">
<div class="tags">
{{ $article->category->title }}</div>
<h2 class="post-title">{{ $article->title }}</h2>
<div class="date">Posted on {{ Carbon\Carbon::parse($article->created_at)->format('F j, Y') }}</div>
</div>
<div class="post-entry">
<p>sss</p>
</div>
<div class="post-footer">
<div class="post-footer-item">
<span class="text">Read More</span> <i class="fa fa-arrow-circle-right"></i>
</div>
</div>
</div><!-- .post-content -->
<?php endforeach ?>
</article><!-- .post -->
and it gave me error Undefined property: stdClass::$category and I don't know why, I already define the relationship in each model Article and Category. Thanks for the help!
In Article model :
public function category()
{
return $this->belongsTo('App\Category', 'category_id');
}
In Category model :
public function article() {
return $this->hasMany('App\Article', 'category_id');
}
Controller :
public function index() {
$article_list = Article::all();
return view('article/index', compact('article_list', $article_list));
}
What you need to do is eager load those relationships in your controller.
When you pull the records do it like this:
$article_list = Article::with('category')->get();
https://laravel.com/docs/5.3/eloquent-relationships#eager-loading
Change this: $article->category->title
To this: $article->category()->title
When you define the relationship in your model you are also creating a function not a property called category.
public function category()
{
return $this->belongsTo('App\Category');
}
In Category model :
public function article() {
return $this->hasMany('App\Article');
}
Controller :
public function index() {
$article_list = Article::all();
return view('article/index', compact('article_list'));
}
This should work for you now like this.

Fetching post comment order by in laravel

I want to fetch comment order by created at but how can i do that?
I did it as usual order by but it didnot work.
#foreach( $post->comnt->take(1)->orderBy('created_at','DESC') as $comments )
#if($post->comnt)
<div class="comments clearfix">
#foreach( $post->comnt->take(1) as $comments )
<div class="each_coments clearfix">
<p> <span class="comment_profile"><img src="{{ asset('img').'/'.$comments->user->image }}" alt=""></span></p>
<p>{{ $comments->user->username }}{{ $comments->comment }}</p>
</div><?php $last_id = $comments->id ?>
#endforeach
<a data-lastid="#if(!empty($last_id)){{$last_id}}#else{{'0'}}#endif" href="">lode more comments</a>
</div>
<?php unset($last_id); ?>
#endif
Here is my post model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = 'posts';
public function user()
{
return $this->belongsTo('App\User');
}
public function likes()
{
return $this->hasMany('App\like');
}
public function comnt()
{
return $this->hasMany('App\comment');
}
}
Maybe
public function comnt()
{
return $this->hasMany('App\comment')->orderBy('created_at','DESC');
}

Resources