how to join laravel model collections - laravel

I am trying to get into models/collections as opposed to straight sql calls in my controllers. I have 2 database tables.
tasks
resources
My Tasks table
taskName
resourceId
someTask
1
task2
2
My Resources table
resourceId
name
1
abc
2
xyz
in straight sql i would do
$sel = "SELECT taskName,resources.resourceId,resources.name ";
$from = "FROM tasks,resources ";
$where = "WHERE tasks.resourceId=resources.resourceId";
and get
someTask,1,abc
task2,2,xyz
how can I do this using models, collections?
I know you all like code I have tried, but I am not sure to where to even begin. I can do the basic $x = tasks::all() stuff...
**Edit
tasks.php
class tasks extends Model
{
/**
* The database connection that should be used by the model.
*
* #var string
*/
protected $table = 'tasks';
protected $connection = 'mysql';
}
resources.php
class resources extends Model
{
protected $table = 'resources';
protected $connection = 'mysql';
}

class tasks extends Model
{
public function resource()
{
return $this->hasOne(resources::class,''resourceId','resourceId');
}
}
$tasks =tasks::with('resource')->get();
foreach($tasks as $task)
{
echo $task->taskName.' '.$task->resourceId.' '.$task->resource->Name;
}

Related

Livewire Datatables - Transform column and filter

I'm trying to substitute column data through callback, that has to return a username, mapped to user unique identifier. The list of usernames is outside of of the model' data and that's where I'm stuck.
I cannot use filterable() with the list of usernames because it will be incorrect since Eloquent won't be able to filter by username - only by user identifier.
The final result of below code is a query which does 'WHERE users.id = The username for X' instead of 'WHERE users.id = X'.
My model:
<?php
class User extends Model
{
protected $table = 'users';
protected $fillable = ['id'];
public static function getNamesProperty()
{
return ['Username #1', 'Username #2'];
}
}
class LogsTable extends LivewireDatatable
{
public $model = User::class;
public $exportable = true;
public $hideable = 'select';
public function builder()
{
return User::query();
}
public function columns()
{
return [
Column::callback(['id'], function ($id) {
return "The username for " . $id;
})->label('Username')->filterOn('users.id')->filterable(User::names()),
];
}
The question is how do I achieve the goal - be able to filter, while displaying username instead of identifier?
There is an answer on GitHub : https://github.com/MedicOneSystems/livewire-datatables/issues/284
Thank you Mark!

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 for display row from subject table?

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

laravel one to Many Relationship with multiple table, query not optimized?

I have a table call table1(i am using some pretended name for tables here) like follow
id_table1 description
And Model is Like
`
class Table1 extends \Eloquent {
public $timestamps = false;
protected $table = 'table1';
protected $fillable = [ 'description'];
protected $primaryKey = 'id_table1';
public function relation5s(){
return $this->hasMany('Relation5','id_table1','id_table1');
}
public function relation4s(){
return $this->hasMany('Relation4','id_table1','id_table1');
}
public function relation3s(){
return $this->hasMany('Relation3','id_table1','id_table1');
}
public function relation2s(){
return $this->hasMany('Relation2','id_table1','id_table1');
}
public function relation1s(){
return $this->hasMany('Relation1','id_table1','id_table1');
}
}
This table is related to 5 tables names relation_table1,relation_table2 ... and so on.
Here is a sample model code for relation tables
<?php
use Illuminate\Database\Eloquent\Relations;
class Relation1 extends \Eloquent {
public $timestamps = false;
protected $table = 'relation_table1';
protected $fillable = [ 'id_table1','idReseller', 'login', 'password', 'type','etc'];
public function childs(){
return $this->hasMany('Relation2','id_relation','id');
}
public function table1(){
return $this->belongsTo('Table1','id_table1','id_table1');
}
public function scopeActive($query){
return $query->whereRaw('type % 2 = 1');
}
public function scopeInactive($query){
return $query->whereRaw('type % 2 = 0');
}
}
`
Problem is when i query below
$level=1; // i am controlling 5 relation tables in same controller via $level from route
$class = "Relation".$level;
$collection = new $class;
$results = $collection->with('Table1')->orderBy($sort,$order)->paginate();
its working showing all result from relation table .. but its doesn't solve n+1 query problem. i mean for every row from relation1 its querying each time on table1 .. any idea how i can solve this ?
thanks in advance
You code is correct, just replace "Table1" by "table1":
$results = $collection->with('table1')->orderBy($sort,$order)->paginate();
Take a look at Eager loading, you are using it with the with method so it will load them in the first query
$level=5
$class = "Relation".$level::with('Table1')->orderBy($sort,$order)->paginate();

Getting started with laravel (4) models

I'm trying out this model-thing, but I can't really get my grasp of it.
For the moment I have two tables (companies and sellers) "companies" as a column named "cResponsibleID" which I want to map to "sID" in "sellers".
models/Companies.php
class Companies extends Eloquent {
protected $table = 'companies';
protected $primaryKey = 'cID';
public function sellers() {
return $this->belongsTo('Sellers','sID');
}
}
models/Sellers.php
class Sellers extends Eloquent {
protected $table = 'sellers';
protected $primaryKey = 'sID';
public function companies() {
return $this->hasMany('Companies','cResponsibleID');
}
}
I then want to do something like Companies::with('sellers.sName')->get() to "translate" cResponsibleID to sName.
Maybe I'm all out wrong.
Thankful for all help.
Can you try printing the result of:
<?php
$company = Companies::with('sellers')->get();
echo '<pre>';
print_r($company->sellers);
And see how they're build up, I blieve the sellers.ANYTHING construction is only meant for multiple nested relations.
for example of a Seller has an Address as a relation, it would be Companies::with('sellers.address')

Resources