Laravel and relationships - php

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');
}

Related

Load Eloquent Model Relationships Child Nodes in Laravel 5.1

I can't return $parent->child() | I get null;
Parent Model
class PrinterSetting extends Model
{
protected $table = 'printer_settings';
//fillables here
protected $with = ['copies'];
public function copies(){
return $this->hasMany(\App\DB\PrinterCopy\PrinterCopy::class, 'printer_id');
}
}
Child Model
class PrinterCopy extends Model
{
protected $table = 'printer_copies';
public function printer(){
return $this->belongsTo(\App\DB\PrinterSetting\PrinterSetting::class, 'id', 'printer_id');
}
}
Code in Controller:
$availablePrinters = $this->printerSetting->where('is_active', 1)->get();
foreach($availablePrinters as $availablePrinter)
{
//working
foreach($availablePrinter->copies() as $copy)
{
//Not working
}
}
I can't find the reason why it's not working.
I Tried to dump $availablePrinter->copies and it work, but ofcourse I can't insert it on foreach() loop.
Please help.
$availablePrinter->copies() return Query builder, you have to use $availablePrinter->copies which is Collection that you can add in loop, Try this
$availablePrinters = $this->printerSetting->where('is_active', 1)->get();
foreach($availablePrinters as $availablePrinter)
{
//working
foreach($availablePrinter->copies as $copy)
{
dd($copy)
}
}
Side note, also fix your belongsTo relation in PrinterCopy model, it should be like this
public function printer(){
return $this->belongsTo(\App\DB\PrinterSetting\PrinterSetting::class,'printer_id');
}

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

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

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