Multiple belongsTo Eloquent - php

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

Related

Unable to fetch results from hasManyJson Using staudenmeir / eloquent-json-relations

I have been working on two tables Category & Product.
In Category Model I have a relationship like
class Category extends Model
{
use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;
public function products(){
return $this->hasManyJson(Product::class,'category_ids[]->id');
}
}
In Products Model I have a relationship like
class Product extends Model
{
use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;
protected $casts = [
'category_ids'=>'json',
];
public function products(){
return $this->belongsToJson(Category::class,'category_ids[]->id');
}
}
Now in my controller when I'm doing trying to get count of each categories product, it is giving me Empty results, below is my controller code.
public function two_category()
{
$list = Category::where('home_status', true)->get();
foreach($list as $ls){
echo $ls->name.' '.count($ls->products).'<br>';
}
dd('ended');
}
This is giving -
Category1 0
Category2 0
And finally this is how my column in product table looks like.

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();

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 and relationships

I have created a few tables like so,
News (id, news_titles_id, create_time)
NewsTitles (id, name)
Now for my Models:
class News extends Eloquent {
protected $table = 'News';
public function title() {
return $this->belongsTo('newsTitles', 'news_titles_id');
}
}
class NewsTitles extends Eloquent {
protected $table = 'NewsTitles';
}
Now if I try and use
$news = News::all();
echo $news->title->name;
I get the undefined property error on title.
What am I doing wrong here? Did I miss something in Laravels eloquent guide?
You have tables as given below:
Table: NewsTitles: (id, name)
Table: News: (id, news_titles_id, create_time)
Models for that:
class NewsTitles extends Eloquent {
protected $table = 'NewsTitles';
public function news()
{
return $this->hasOne('News', 'news_title_id');
}
}
class News extends Eloquent {
protected $table = 'News';
public function title()
{
return $this->belongsTo('NewsTitles', 'news_title_id');
}
}
Use like:
$news = News::with('title')->all(); // returns a collection (more than one)
echo $news->first()->title->name; // Get first News
echo $news->get(0)->title->name; // Get first News
echo $news->get(1)->title->name; // Get second News
Or you may loop:
foreach($news as $item) {
echo $item->title->name;
}
I think it needs to be
return $this->hasOne('NewsTitle', 'news_title_id');
since a News object "has one" news title.
And the inverse of the relationship, on the NewsTitle model would be
public function news()
{
return $this->belongsTo('News', 'news_title_id');
}

Make Multiple Eloquent Relationship & there's A Where Clause

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

Categories