Make Multiple Eloquent Relationship & there's A Where Clause - php

Now I have news category,news, and news image table structure like :
and i want to make a list like :
how i make list like that with eloquent relationship ( whereHas or Has ) ?
PS: Sometimes news have'nt an image

Assuming that your model is called Category and has a relationship called news which further has a relationship called image, you'd simply do the following.
$categories = Category::with(['news', 'news.image'])->all();
That would grab all categories with their news, and the image relationship if they have one.
if you don't have the relationships setup, it'd look something like this.
Category model:
<?php
class Category extends Eloquent
{
protected $table = 'category';
public function news()
{
return $this->hasMany('News');
}
}
News model:
<?php
class News extends Eloquent
{
protected $table = 'news_main';
public function category()
{
return $this->belongsTo('Category');
}
public function image()
{
return $this->hasOne('NewsImage');
}
}
News Image model:
<?php
class NewsImage extends Eloquent
{
protected $table = 'news_img';
public function news()
{
return $this->belongsTo('News', 'id_news');
}
}
NOTE
It may be worth changing the names of the tables and some of the fields to have a more uniform and sensible feel to the naming structure.
categories category_id
news news_id
news_images

Related

Rretrieving data from foreign key, One to One Relationship. Laravel

I am trying to retrieve value from foreign key table with one to one relation. I have defined two models:
1. Blog
class Blog extends Model
{
//
protected $table = 'blogs';
public function blog_category()
{
return $this->hasOne('App\Blog_Category');
}
}
2. Blog Category
class Blog_Category extends Model
{
//
protected $table=('blogs_categories');
public function blog()
{
return $this->belongsTo('App\Blog');
}
}
I have got blogs_categoryid in blogs table that has been referenced to id from blogs_categories table.
I have tried following:
{{$blog->blogs_categoryid->category}}
But it is showing "trying to get property of non-object". What is going wrong here? Can anyone help me?
Blog model content should be:
class Blog extends Model
{
protected $table = 'blogs';
public function blog_category()
{
return $this->hasOne('App\Blog_Category', 'blogs_categoryid');
}
}
Then use with when you want it to query relation table:
$blog = Blog::with('blog_category')->get();
$categoryObject = $blog->blog_category;
$categoryId = $categoryObject->id;

Multiple belongsTo Eloquent

I have 3 models objects, namely: Categories, Category_products & Products
Categories:
<?php
class Categories extends Model
{
protected $table = 'categories';
public function product_ids() {
return $this->hasMany("app\Models\categories\Category_products", "category_id", "id");
}
?>
Category_products:
<?php
class Category_products extends Model
{
protected $table = 'category_products';
public function product_ids(){
return $this->belongsTo('app\Models\categories\Category');
}
public function products(){
return $this->hasOne("app\Models\Product", "id", "product_id");
}
}
?>
And Product:
<?php
class Product extends Model {
protected $table = 'products';
public function product(){
return $this->belongsTo("app\Models\categories\Category_products");
}
?>
Now in my CategoryController I do:
$this->data["products"] = Categories::find($id)->product_ids()->products()->get();
But now I get an error :
Call to undefined method Illuminate\Database\Query\Builder::products()
How can I do this the right way ?
OK, I'm going to try.
I guess you missed something when reading the Laravel documentation.
You don't have to create the category_products Models because it's your pivot table between your Categories and your Product.
"Normally", you should have something like this :
Products :
. id
. name
Categories :
. id
. name
category_product (alphabetically ordered name)
. product_id
. category_id
And your Models:
class Category extends \Eloquent {
public function products()
{
return $this->belongsToMany('namespace\to\your\model\Product');
}
}
class Product extends \Eloquent {
public function categories()
{
return $this->belongsToMany('namespace\to\your\model\Category');
}
}
Then you can do the following :
$this->data["products"] = Category::find($id)->products;
or
$this->data["products"] = Category::find($id)->products()->get();
Laravel will take care to call the pivot table for you.
It's not common to name your class with a plural, get used to name your class with their singular
And see also : http://laravel.com/docs/5.0/eloquent#many-to-many

Check if category belongs to post

Hello I'm trying to make script that show all categories and if category belongs to post this category should be checked with checkbox. My script wont works could you help me please. It shows only one checked category when have to shows two.
Controller Category model:
class Category extends Eloquent {
protected $table= "categories";
public function posts(){
return $this->belongsToMany('Post');
}
}
Post model
class Post extends Eloquent {
protected $table = 'posts';
public function categories(){
return $this->belongsToMany('Category');
}
}
catRelation:
[{"id":"45","post_id":"132","category_id":"1","created_at":"2014-12-26 20:32:41","updated_at":"2014-12-26 20:32:41"},{"id":"46","post_id":"132","category_id":"3","created_at":"2014-12-26 20:32:41","updated_at":"2014-12-26 20:32:41"}]
all categories: [{"id":"1","name":"Laravel","slug":"laravel","created_at":"-0001-11-30 00:00:00","updated_at":"-0001-11-30 00:00:00"},{"id":"3","name":"PHP","slug":"php","created_at":"-0001-11-30 00:00:00","updated_at":"-0001-11-30 00:00:00"}]
A category shouldn't ever belong to a post, but rather a post should belong to a category.
I assume catRelation is your pivot table. It's worth nothing that you need neither id, created_at or updated_at for this.
Example models:
class Post extends Eloquent
{
protected $table = 'posts';
public function category()
{
return $this->belongsToMany('Category', 'catRelation', 'category_id');
}
}
class Category extends Eloquent
{
protected $table = 'categories';
public function post()
{
return $this->belongsToMany('Post', 'catRelation', 'post_id');
}
}
Note: I may have got the final arguments in belongsToMany the wrong way around.

Laravel 4 eager loading and categories, subcategories, articles

Hi i thought i can handle this myself, but actually i don't know how to bite it.
I am trying to categorise my programs. There will be only 2 levels of categories:
1 CATEGORY
2 |-Subcategory
I want it to be as simple as possible.
- program can belong to only one subcategory,
- categories can have many subcategories,
- subcategories can have many programs,
Of course i would like to list all programs from subcategories, when someone choose a main category.
I am also not sure about my current database tables structure and relationship in models.
Tables in database:
programs: id, title, description, program_subcategory_id
programs_categories: id, name
programs_subcategories: id, name, program_category_id
Models:
Program.php
class Program extends Eloquent {
protected $table = 'programs';
public function user()
{
return $this->belongsTo('User');
}
public function subcategory()
{
return $this->belongsTo('ProgramSubcategory', 'program_subcategory_id');
}
}
ProgramCategory.php
class ProgramCategory extends Eloquent {
protected $table = 'programs_categories';
public function subcategories()
{
return $this->hasMany('ProgramSubcategory');
}
}
ProgramSubcategory.php
class ProgramSubcategory extends Eloquent {
protected $table = 'programs_subcategories';
public function programs()
{
return $this->hasMany('Program');
}
public function category()
{
return $this->belongsTo('ProgramCategory');
}
}
Actual controllers:
ProgramsController.php
class ProgramsController extends BaseController {
public function index()
{
$programs = Program::with('subcategory')->orderBy('programs.id', 'desc')->paginate(5);
$acategories = ArticleCategory::All();
$pcategories = ProgramCategory::All();
return View::make('programs.index', compact('programs', 'acategories', 'pcategories'));
}
}
ProgramsSubcatecories.php
class ProgramsSubcategories extends BaseController {
public function index($cname)
{
$programs = ProgramSubcategory::whereAlias($cname)->first()->programs()->orderBy('id', 'DESC')->paginate(10);
$pcategories = ProgramCategory::All();
$scategories = ProgramSubcategory::All();
$acategories = ArticleCategory::All();
return View::make('programs.index', compact('programs', 'pcategories', 'scategories ', 'acategories'));
}
public function show($cname, $id)
{
$category = ProgramSubcategory::whereAlias($cname)->first();
$program = $category->programs()->findOrFail($id);
$pcategories = ProgramCategory::All();
$acategories = ArticleCategory::All();
return View::make('programs.show', compact('program', 'category', 'pcategories', 'scategories ', 'acategories'));
}
}
It is not a problem for me to list all items from one category with eager loading. But i have problem how to do it with 2-levels categories.
Please advise how to start it.
You are not looking for eager loading, you need to solve how to manage hierarchical data in your database.
Nested sets model serves this purpose very well. You should read some theory on Wiki: http://en.wikipedia.org/wiki/Nested_set_model
Fortunately, there are Eloquent implementations already.
To mention some:
- Baum (the best free, imho), https://github.com/etrepat/baum
- Laravel Nested Set, https://github.com/atrauzzi/laravel-nested-set
- Laravel4-nestedset, https://github.com/lazychaser/laravel4-nestedset
and the paid one (surely highest quality as well)
from Cartalyst company - https://cartalyst.com/manual/nested-sets

One-to-many relationship not working

I've a one-to-many relationship with models
Article
class Article extends Eloquent {
protected $table = 'articles';
public function categories()
{
return $this->belongsTo('ArticleCategory');
}
}
ArticleCategory
class ArticleCategory extends Eloquent {
protected $table = 'articles_categories';
public function articles()
{
return $this->hasMany('Article');
}
}
In my controller I'm trying to grab all articles from a category
$categories = ArticleCategory::find(1);
$article = $categories->articles;
return $article;
and that works perfectly.
But when I’m trying to make an inverse
$article = Article::find(1);
$category = $article->categories;
return $category;
I'm getting null. I should get a category return for an article id in find().
Database tabels:
- articles: Id | title | description | category_id
- articles_categories: Id | title
Since it's one to many relationship you can easily do this
$category = ArticleCategory::find($article->category_id);
I think the error is in the naming in your database fields.
The field in your articles table which is pointing to the articles_categories should be name articles_categories_id.
Try this
public function categories()
{
return $this->belongsTo('ArticleCategory','category_id');
}

Categories