I am setting up two Models. Let's assume we have a portfolio and portfolio_category table
Table portfolio
id
cat_id
name
status
Table portfolio_category
cat_id
cat_name
Model
class Portfolio extends \Eloquent {
protected $fillable = [];
public function portfolio_category()
{
return $this->hasMany('Portfolio_category');
}
}
class Portfolio_category extends \Eloquent {
protected $fillable = [];
public function portfolio()
{
return $this->belongsTo('Portfolio');
}
}
My code:
$data = Portfolio::all();
foreach($data as $value){
$id = $value['id'];
$name = $value['name'];
$cat_name = $value['cat_name'];
}
I want to display category name but it shows null values.
I am pretty confused, what went wrong? any idea!!!
I got my answer
$data = Portfolio::join('portfolio_category', 'portfolio_category.cat_id', '=', 'portfolio.cat_id')->get();
foreach($data as $value){
$id = $value['id'];
$name = $value['name'];
$cat_name = $value['cat_name'];
}
Your relationships are not defined correctly. In your code, you've tried to define the Portfolio as the parent, and the Portfolio_category as the child. However, your tables are setup such that the Portfolio_category is the parent and the Portfolio is the child. Basically, the table that contains the foreign key (portfolio table has foreign key to portfolio_category) should be on the belongsTo side.
So, instead of portfolio hasMany portfolio_category and portfolio_category belongsTo portfolio, it needs to be switched to portfolio_category hasMany portfolio and portfolio belongsTo portfolio_category.
Additionally, I'm assuming these were removed for brevity, but the table names and the primary key on your portfolio_category table do not conform to Laravel conventions, so you need to specify these properties in the model.
Your models should look like:
class Portfolio extends \Eloquent {
protected $table = 'portfolio';
protected $fillable = [];
public function portfolio_category()
{
return $this->belongsTo('Portfolio_category');
}
}
class Portfolio_category extends \Eloquent {
protected $table = 'portfolio_category';
protected $primaryKey = 'cat_id';
protected $fillable = [];
public function portfolios()
{
return $this->hasMany('Portfolio');
}
}
Now you can access the related tables through the relationships:
$data = Portfolio::with('portfolio_category')->get();
foreach($data as $value){
$id = $value->id;
$name = $value->name;
$cat_name = $value->portfolio_category->cat_name;
}
For more on the Eloquent ORM, the documentation can be found here (L4.2) or here (L5.0).
Related
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;
What am I trying?
Get a particular category and it's associated Sub Categories
Category Model
class Category_Model extends Model
{
protected $table = "tblcategory";
protected $primaryKey = "CategoryID";
public $timestamps = false;
public function Subcategories()
{
return $this->hasMany('\App\Models\Skill\SubCategory_Model');
}
}
Sub Category Model
class SubCategory_Model extends Model
{
protected $table = "tblsubcategory";
protected $primaryKey = "SubCategoryID";
public $timestamps = false;
}
Action Method
public function SubCategories($category)
{
$Categories = \App\Models\Skill\Category_Model
::where("Category", "=", $category)
->Subcategories;
dd($Categories);
}
When I run the code. I get below error
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'tblsubcategory.category__model_id' in 'where clause' (SQL: select *
from tblsubcategory where tblsubcategory.category__model_id = 1
and tblsubcategory.category__model_id is not null)
From the comments, it is most likely that your subcategory table doesn't have a category_model_id but likely a category_id. By default, Laravel tries to extrapolate the name of the foreign column from the model name (in this case Category_Model, which explains the category_model_id. Changing the class to:
class Category_Model extends Model
{
protected $table = "tblcategory";
protected $primaryKey = "CategoryID";
public $timestamps = false;
public function Subcategories()
{
return $this->hasMany('\App\Models\Skill\SubCategory_Model', 'category_id')->get(); // Or whatever the column is actually called
}
}
should solve the issue.
To return both the category object and its subcategories, change the action code to:
public function SubCategories($category)
{
$Categories = \App\Models\Skill\Category_Model
::where("Category", "=", $category)
->with("Subcategories")
->first();
dd($Categories);
}
The $Categories should also now contain a Subcategories object, accessed via $Categories->Subcategories, which should return a collection of Subcategory objects. If you wanted to see each one, you would loop through with a foreach
foreach($Categories->Subcategories AS $Subcategory){
echo $Subcategory->name;
// etc etc.
}
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
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');
}
I am having issues getting the relationship array back when eager loading in laravel 4. for example:
controller:
foreach (Apps::with('extra')->get() as $app)
{
print_r($app->toArray());//returns array but my relationship array at the bottom says null
echo $app->extra; //this will show my relationship details
}
model:
class Apps extends Eloquent
{
protected $connection = 'mysql_2';
protected $table = 'apps';
public $timestamps = false;
protected $primaryKey = 'name';
public function host()
{
return $this->belongsTo('Hosts','name');
}
public function extra()
{
$this->primaryKey='app_ip';
return $this->hasone('Extra','ip');
}
//other functions below.......
}
class Extra extends Eloquent
{
protected $connection = 'mysql_3';
protected $table = 'extra';
public $timestamps = false;
protected $primaryKey = 'ip';
public function app(){
return $this->belongsTo('Apps', 'app_ip');
}
mysql:
My mysql tables were not created through laravel they were previously existent. the app_ip column in the Apps table relates to the ip column in the extra table. it is a 1 to 1 relationship and I have specified the primary key in the relationship function. I am getting relationships back so I know that it is working.
I am able to get relationship data back when I call the function directly, but it does not show the relationship data when I try and print the full array. The main goal is to be able to return both the relationship columns and the app columns in one response.
You need to do this:
$apps = Apps::all();
$apps->load('extra');
foreach ($apps as $app)
{
print_r($app->toArray()); // prints your relationship data as well
}
What you have should work and iterating through the collection or using ->load() to eager load shouldn't make a difference. Are you using the visible restriction on your models? If so you will need to include the relationships.
class Apps extends Eloquent {
protected $visible = array(
'id',
'name',
'created_at',
'extra', // Make the relationship 'visible'
);
public function extra()
{
return $this->hasMany('Extra');
}
}