Laravel Eloquent for display row from subject table? - laravel

i have three database tables
category (id,name)
subcategory (id,name,category_id) foreign_key category_id on table category(id).
subject(id,name,subcategory_id) foreign_key subcategory_id on table subcategory (id).
i want a row containing the following -
subject_id subject_name category_name subcategory_id
how to do this using eloquent .and if approach is wrong .please suggest a good method to achieve the same .

Assuming you have the following models:
// Category Model
class Category extends \Eloquent {
protected $table = "category";
public function subcategory(){
$this->hasMany('Subcategory','category_id');
}
}
// Subcategory Model
class Subcategory extends \Eloquent {
protected $table = "subcategory";
public function category(){
$this->belongsTo('Category', 'category_id');
}
pubic function subject(){
$this->hasMany('Subject', 'subcategory_id');
}
}
// Subject model
class Subject extends \Eloquent {
protected $table = "subject";
public function subcategory(){
$this->belongsTo('Subcategory','subcategory_id');
}
}
You can get the data in your controller as follows:
// for subject with id 1
public function getOneRow(){
$subject = Subject::with('subcategory.category')->findOrFail(1);
//subject_id = $subject->id
//subject_name = $subject->name
//subcategory_id = $subject->subcategory->id
//category_name = $subject->subcategory->category->name
return array("subject_name"=>$subject->name, "category_name"=>$subject->subcategory->id, "subcategory_name"=>$subject->subcategory->category->name);
}
// for all subjects
public function getOneRow(){
$subjects = Subject::with('subcategory.category')->all();
$out = array();
foreach($subjects as $subject){
// each row
//subject_id = $subject->id
//subject_name = $subject->name
//subcategory_id = $subject->subcategory->id
//category_name = $subject->subcategory->category->name
$out[] = array("subject_name"=>$subject->name, "category_name"=>$subject->subcategory->id, "subcategory_name"=>$subject->subcategory->category->name);
}
return $out;
}
Edit for Laravel 5.1
Your models will be defined differently. Here's an example. Or follow the docs:
// Category Model Laravel 5.1
use Illuminate\Database\Eloquent\Model;
class Category extends Model {
protected $table = "category";
public function subcategory(){
$this->hasMany('Subcategory','category_id');
}
}
Edit: Completed the functions with return statements as requested in comment

Related

Laravel filtering query results with relations

I have this relations
and defined models for all 3 tables
class Employee extends Model
{
use HasFactory;
protected $table = 'employees';
public function departments()
{
return $this->belongsToMany(Department::class, 'dept_emp', 'emp_no', 'dept_no', 'emp_no', 'dept_no');
}
}
class Department extends Model
{
use HasFactory;
protected $table = 'departments';
}
class Dept_emp extends Model
{
use HasFactory;
protected $table = 'dept_emp';
}
And in my controller
$employees = Employee::with('departments')->paginate(50);
I want to filter this query result to be able to select only one chosen department and not all of them.
I tried adding to employee model this function
public function scopeDepartment($query, $department)
{
return $query->where('dept_no',$department);
}
but it isn't working. Can someone advice me how to filter query results with relations?
you can query within with relation as like
$employees = Employee::with(['departments' => function($q) use ($dept_id){
$q->where('dept_no',$dept_id);
}])->paginate(50);
$dept_id is the id of department i.e $dept_id = $request->department_id something like

laravel 5.7 correct way of getting results on many to many relation

I'm learning laravel framework and I've a pretty straightforward question:
I have three tables:
Foods table:
foods
--------------
id | name
Ingredients table:
ingredients
---------------
id, | name
Pivot table:
food_ingredient
---------------
food_id | ingredient_id
In the models I have the "belongsToMany" methods:
Food Model:
public function ingredients(){
return $this->belongsToMany('App\Models\Ingredient');
}
Ingredient Model:
public function foods(){
return $this->belongsToMany('App\Models\Food');
}
FoodsController (index):
$foods = Food::all();
foreach($foods as $food){
$food->ingredients = Ingredient::join('food_ingredient','food_ingredient.id','=','ingredients.id')
->where('food_ingredient.food_id',$food->id)->get();
}
I want to get the ingredients information (just the name until now) of each food, and this query (the one is in the foreach loop) does it, but I'm not sure if I'm doing it in a right way. I'm not using the belongsToMany relations so...there must be something wrong in my understanding.
How could I get the names of the ingredients?
Until know just those names are ok, but I'll add a third table "allergens" and it's pivot table "allergen_ingredient" soon. Then, I'll have to get each food, their ingredients, and also the allergens of each ingredient. So that, I want to do it well from now.
Thank you in advance.
Food Model
class Food extends Model
{
protected $table = 'foods';
protected $primaryKey = 'food_id';
public $incrementing = TRUE;
public $timestamps = FALSE;
protected $fillable = [
'food_name'
];
public
function ingredients()
{
return $this->belongsToMany(Ingredient::class, 'food_ingredients', 'food_id', 'ingredient_id');
}
}
Ingredient Model
class Ingredient extends Model
{
protected $table = 'ingredients';
protected $primaryKey = 'ingredient_id';
public $incrementing = TRUE;
public $timestamps = FALSE;
protected $fillable = [
'ingredient_name'
];
public
function foods()
{
return $this->belongsToMany(Food::class, 'food_ingredients', 'ingredient_id', 'food_id');
}
}
and you can call it this way:
$foods = Food::all();
foreach( $foods as $food )
{
foreach( $food->ingredients as $ingredient )
{
echo $ingredient->ingredient_name . " <br>";
}
}
food_ingredients is the pivot table name

Laravel Eloquent many to many relationship with translation

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');
}
}
the last model is for the relationship between the two tables above:
class ProductAccessori extends Model {
protected $table = 'accessori_products';
public function accessoriProducts() {
return $this->belongsTo('App\Product', 'accessori_id', 'products_id');
}
}
I'm trying to get the accessories of each product and to get also the translation but I'm having a lot of problem with this.
It's my first time with a many to many relation with translations too.
Can anyone put me on the right direction?
controller
$products = Product::has('accessori')->with([
'productsLang ',
'accessori' => function ($accessori){
$accessori->with([
'accessoriLang'
]);
}
])->get();
return $products;
you'll get products with accessori that has accessoriLang.

Laravel | oneToMany with two foreign keys

I have two tables, invoice_header and invoice_detail
Both tables have loc_id and invo_no as reference keys between them.
How can I link them inside the model, can I use array for foreign keys?
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class InvoiceDetail extends Model
{
protected $table = 'invoice_detail';
public $timestamps = false;
protected $fillable = ['invo_no','loc_id','serial','item_id','qty','rtp','cost',
'discount','type'];
public function item(){
return $this->belongsTo('App\InvoiceHeader', ['loc_id', 'invo_no']);
}
}
https://laravel.com/docs/5.5/eloquent-relationships#one-to-many
You will want a details model and and invoice header model and invoice model and inter connect them.follow the article or rename your model to invoice and make to functions
//details
public function invoice(){
return $this->belongsTo(Invoice::class);
}
//invoice model
public function details(){
return $this->hasMany(InvoiceDetails::class);
}
public function headers(){
return $this->hasMany(InvoiceHeaders::class);
}
//headers model
public function invoice(){
return $this->belongsTo(Invoice::class);
}
//then you can get details and headers through
$invoice = Invoice::find(1);
$details = $invoice->details;
$headers = $invoice->headers;

Populate laravel object with relationships

I want to populate Every CustomerEvent with the Customer related to the CustomerEvent.
When I Loop through the object and call to $customerevent->customer foreach object I can get the customer related to that event but Can I populate the all objects in the main object without looping through every single event ?
I want to do something like this:
$typeOne = CustomerEvent::typeOne()->get();
$customersWithTypeOne = $typeOne->Customers;
Here my code:
Table 1: "events"
id, customer_id
Model for Table 1 "CustomerEvent":
<?php
class CustomerEvent extends Eloquent{
protected $guarded = ['id'];
public $table = "event";
protected $softDelete = true;
public function scopeTypeOne($query)
{
$followUps = $query->where('type_id', '=', '1');
}
public function Customers()
{
return $this->belongsTo('Customer', 'customer_id');
}
}
Table 2: "customers"
id
Model for Table 2 "Customers":
<?php class Customer extends BaseModel{
protected $guarded = ['id'];
}
EventController:
public function index()
{
$typeOne = CustomerEvent::typeOne()->get();
$customersWithTypeOne = $typeOne->Customers;
dd($customersWithTypeOne);
}
From you database scheme I see customer has many events, so I would recommend to define this relationship in you Customer model.
class Customer extends BaseModel{
protected $guarded = ['id'];
public function events()
{
return $this->hasMany('CustomerEvent', 'customer_id');
}
}
Then you will be able to query customers with events:
$customersWithTypeOne = Customer::whereHas('events', function($query){
$query->where('type_id', 1);
})->get()
Maybe Ardent can help you: https://github.com/laravelbook/ardent
It's an extension for Eloquent models and very popular.

Resources