How to query Eloquent relational tables based on json ids - php

I have a articles table with a field named article_categories.
I have a categories table with id field.
In my Article Model I have defined:
public function category(){
return $this->hasMany(Category::class,'id','article_categories');
}
the categories in the articles table are saved as json like ["1","3","24"]
in my ArticleController I want to retrieve all categories of a specific article.
In my edit function in the ArticleController I have this function:
public function edit(Article $article)
{
$category_ids = implode(',',json_decode($article->article_categories)) ; //this gives me 1,3,24
/////////
// HERE SHOULD COME THE QUERY WHICH I DON'T KNOW
// $article_categories = ??????????
////////
$categories = Category::all();
return view('article.edit', compact('articles','categories','article_categories'));
}
From what I've researched, there is no way to do this with Laravel but I don't know if this is true or not. I'm using Laravel 8.
Can anyone help me?

First of all you should know that you violated a many-to-many relation in a single column and that's not valid. What you should do is a pivot table article_category or category_article and in both Article and Category models you will define a many-to-many relation
like so
class Article extends Model
{
public function categories()
{
return $this->belongsToMany(Category::class);
}
}
class Category extends Model
{
public function articles()
{
return $this->belongsToMany(Article::class);
}
}
And in your controller you can do
public function edit(Article $article)
{
$categories = Category::all();
return view('article.edit', compact('article','categories'));
}
And in the view you will have direct access to $article->categories
In your current situation you can do this
public function edit(Article $article)
{
$category_ids = json_decode($article->article_categories)
$article_categories = Category::whereIn('id', $category_ids);
$categories = Category::all();
return view('article.edit', compact('article','categories','article_categories'));
}

Related

How to get a custom collection based on a data that is most repeated (from top to bottom))

I have a table like this:
Basically this table is named favourite_products and contains product ids that are added as favourite for users.
Now I wanted to get a collection of most added product from this table.
So in this case, a product with an id of 10 would be on top of the collection.
But I don't know how to get this collection ordering by from most repeated product id (prd_id)...
Here is the Model:
class FavouriteProduct extends Model
{
protected $table = 'favourite_products';
protected $fillable = ['usr_id','prd_id'];
public function user()
{
return $this->belongsTo(User::class, 'usr_id');
}
public function product()
{
return $this->belongsTo(Product::class, 'prd_id');
}
}
UPDATE #1:
Product.php Model:
public function favouritees()
{
return $this->belongsToMany(User::class, 'favourite_products', 'prd_id', 'usr_id');
}
I think the following code solve your problem:
$most_liked_products = DB::table('favourite_products')
->select(DB::raw('count(prd_id) as total'), id)
->groupBy('total')
->orderByDesc('total')
->get();
Please try it and give your feedback
try use this
public function example()
{
$data=FavouriteProduct::orderBy('prd_id', 'ASC')->get();
dd($data);
}

How to fetch data along with relationship data in Laravel using with keyword?

How can I fetch data along with blog category and blog tags from Blogs table using with in query.
Below is my model and controller code, I am getting Get Blogs Api Error instead of the blogs data.
Blog Controller
public function getBlogs()
{
try {
$blogs = Blog::where('status', 1)
->with('category')
->with('tag')
->with('user')
->with('comment')
->orderBy('id', 'desc')
->paginate(5);
return response()->json($blogs);
} catch (\Illuminate\Database\QueryException $e) {
$e = "Get Blogs Api Error";
return response()->json($e);
}
}
Blog Model
class Blog extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function category()
{
return $this->hasMany(Category::class);
}
public function tag()
{
return $this->hasMany(Tag::class);
}
public function comment()
{
return $this->hasMany(Comment::class);
}
}
User Model
public function blog_user()
{
return $this->hasMany(Blog::class);
}
Blog Category Model
public function blog_category()
{
return $this->belongsTo(Blog::class);
}
Blog Tag Model
public function blog_tag()
{
return $this->belongsTo(Blog::class);
}
Blog Comment Model
public function blog_comment()
{
return $this->belongsTo(Blog::class);
}
Database table structure
blogs table structure
blog_categories table structure
blog_tags table structure
First of all change names to plural. not singular. as you are using one to many. and use belongsToMany() method. not hasMany().
public function categories(){
return $this->belongsToMany(Category::class);
}
and change the name of pivot table to blog_category not blog_categories. It will work. and your BlogCategory model will look like this.
class BlogCategory extends Model {
protected $table = 'blog_category';
public function blog() {
return $this->belongsTo( Blog::class );
}
}
now you can get blogs like this.
$blogs = Blog::with( 'categories' )->get();
and this is how you will fetch blog for any category.
$category = BlogCategory::where( 'category_id', $category->id )->first();
dd( $category->blog );

How to get only active element from many to many relationship with translation in laravel

I have a problem with a many to many relationship and the translations of the terms.
I have 4 tables:
products
- id, price, whatever
products_lang
- id, product_id, lang, product_name
accessori
- id, active
accessori_lang
- id, accessori_id, lang, accessori_name
I'm trying to assign accessories to products with an intermediate table named:
accessori_products
this is the model for Product:
class Product extends Model {
protected $table = 'products';
public function productsLang () {
return $this->hasMany('App\ProductLng', 'products_id')->where('lang','=',App::getLocale());
}
public function productsLangAll() {
return $this->hasMany('App\ProductLng', 'products_id');
}
public function accessori() {
return $this->belongsToMany('App\Accessori', 'accessori_products');
}
}
this is the model for productLng:
class ProductLng extends Model {
protected $table = 'products_lng';
public function products() {
return $this->belongsTo('App\Product', 'products_id', 'id');
}
}
Then I have the model for Accessori:
class Accessori extends Model {
protected $table = 'accessori';
public function accessoriLang() {
return $this->hasMany('App\AccessoriLng')->where('lang','=',App::getLocale());
}
public function accessoriLangAll() {
return $this->hasMany('App\AccessoriLng');
}
public function accessoriProducts() {
return $this->belongsToMany('App\Products', 'accessori_products', 'accessori_id', 'products_id');
}
}
And the model for AccessoriLng:
class accessoriLng extends Model {
protected $table = 'accessori_lng';
public function accessori() {
return $this->belongsTo('App\Accessori', 'accessori_id', 'id');
}
}
I get the results by this:
$products = Product::has('accessori')->with([
'productsLang ',
'accessori' => function ($accessori){
$accessori->with([
'accessoriLang'
]);
}
])->get();
return $products;
but I want to get only the active accessories something like where accessori.active = 1 but I really don't know where to put it. I've tried in different way but I'm stuck on it by 2 days.
IIRC you don't need a model for the intermediate table on your many to many relationships.
If you want to return Products where Accessori is active you can use whereHas on the Product model.
$prod = Product::whereHas('accessori', function($query) {
$query->where('active', 1);
})->get();
Where the $query param will be running on the Accessori model.
You can do the inverse as well with Accessori to Product.
$acessoris = Accessori::where('active', 1)->whereHas('accessoriProduct')->with(['accessoriLang', 'accessoriProducts.productsLang'])->get();

Laravel Many to Many relationship gets partial results

I have Course and Category Models with many to many relationship between them. So I created CategoryCourse Model to decompose relationship. Here are my three models:
class CategoryCourse extends Model
{
private $foreignkeys = [
'$category_id','$course_id'
];
public function categories()
{
return $this->belongsToMany('App\Category');
}
public function courses()
{
return $this->belongsToMany('App\Course');
}
}
class Category extends Model
{
protected $title = ['title'];
public function categorycourse()
{
return $this->hasMany('App\CategoryCourse');
}
}
class Course extends Model
{
protected $fillable = [
'title', 'desc'
];
public function categorycourse()
{
return $this->hasMany('App\CategoryCourse');
}
}
In my controller I have method as follows:
public function getCoursesByCategory(Request $request, $id)
{
$id = Hashids::decode($id);
$categories = Category::findOrFail($id[0]);
$courses = $categories->categorycourse()->get();
return view('courses',compact('courses'));
}
I have three tables in database, they are categories, courses and category_courses. My view is displaying results from category_courses but not results from courses. I am learning laravel. Can any one please help? I want to display all courses that belong to a category, in my view.
Here is my view code:
#foreach($courses as $course)
{{$course->title}}
#endforeach
You have to change your code to:
class Category extends Model
{
protected $title = ['title'];
public function courses()
{
return $this->belongsToMany('App\Course', 'category_course', 'category_id', 'course_id');
}
}
The relationship should be in Category only.
And then you call:
$courses = $categories->courses;

Picking the right type of relationship using Laravel and Eloquent

I have three tables in my database.
Posts
Authors
Categories
When viewing an Author page I want to be able to view all of the author's Posts and also the category of the post.
When viewing a Category index page I want to be able to view all of the Posts for that category and also include the Author with each Post.
When viewing a Post I want to be able to include the Category and Author
What type of relationship can I use to achieve this?
One to one, One to Many, Many to many, or polymorphic
Thanks in advance.
You can create your relations like this:
class Post extends Eloquent {
public funcion category()
{
return $this->belongsTo('Category');
}
public funcion author()
{
return $this->belongsTo('User');
}
}
class Author extends Eloquent {
public funcion posts()
{
return $this->hasMany('Post');
}
}
class Category extends Eloquent {
public funcion posts()
{
return $this->hasMany('Post');
}
}
And then use them this way:
$author = Author::find(1);
foreach($author->posts as $post)
{
echo $post->title;
echo $post->author->name;
}
$category = Category::find(1);
foreach($category->posts as $post)
{
echo $post->title;
echo $post->author->name;
}
$post = Post::find(1);
echo $post->category->title;
echo $post->author->name;
I have done something like this :
db table =
users : id name
debates : id post user_id
now in model
class User extends SentryUserModel {
public function debates()
{
return $this->hasMany('Debate', 'user_id');
}
}
and
class Debate extends Eloquent {
public function user()
{
return $this->belongsTo('User', 'id');
}
}
now in query
$debate= Debate::find(1);
echo $debates->user->name;
echo $debates->user->id;
it is giving a null result.
Changing this two solve the problem . (Do now know why we cant use foreign key here. If anyone know this please do inform ).
class User extends SentryUserModel {
public function debates()
{
return $this->hasMany('Debate');
}
}
and
class Debate extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}

Categories