Laravel 5 Nested models with parent relationship - laravel

I am struggling with Laravel 5 nested models with a parent-child relationship. I manage to get the information i need but it takes 8 - 9 queries, and i believe that it should be doable with only 4.
The 3 tables look similar to this:
Article table
id | title | description | parent_id | user_id
-----------------------------------------------
1 | Some title | Awes. text | null | 1
2 | Child title | Super text | 1 | 2
3 | Child2title | Super text | 1 | 1
Comments table
id | article_id | user_id | comment
1 | 1 | 2 | Funny commment
And the Users table
id | name | ... | ...
And i have the following models defined:
Article model
class Article extends Model {
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id')->select(array('id', 'name', 'points'));
}
public function comments()
{
return $this->hasMany('App\Comment')->with('user');
}
public function children()
{
return $this->hasMany('App\Article', 'parent_id', 'id')->with('user', 'comments')->select(array('id', 'parent_id', 'description', 'votes', 'updated_at', 'user_id'));
}
}
Comment model
class Comment extends Model {
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id')->select(array('id', 'name', 'points'));
}
public function article()
{
return $this->belongsTo('App\Article');
}
}
User model
class User extends Model {
protected $table = 'users';
protected $fillable = ['name', 'email', 'password', 'points'];
protected $hidden = ['email', 'role', 'password', 'remember_token'];
}
Now I can get the parent article with user and comments (and users from comments) together with all the child articles with again the user that posted the article + all comments with users that posted the comments with the following query:
$article = Article::with('user', 'comments', 'children')->findOrFail(1);
But it results in 8 queries
select * from `articles` where `articles`.`id` = ? limit 1
select `id`, `name`, `points` from `users` where `users`.`id` in (?)
select * from `comments` where `comments`.`article_id` in (?)
select `id`, `name`, `points` from `users` where `users`.`id` in (?, ?, ?)
select `id`, `parent_id`, `description`, `votes`, `updated_at`, `user_id` from `articles` where `articles`.`parent_id` in (?)
select `id`, `name`, `points` from `users` where `users`.`id` in (?, ?, ?, ?)
select * from `comments` where `comments`.`article_id` in (?, ?, ?, ?, ?, ?)
select `id`, `name`, `points` from `users` where `users`.`id` in (?, ?, ?, ?, ?, ?, ?, ?)
I have tried many things but i keep getting 8 - 9 queries.
I feel like this should be doable with only 4 queries:
Get parent article
Get childs articles
Get comments
Get users
Am I missing something ?

Related

Laravel: Get root class in nested relationship query

How can I get the root class in a nested eager relationship? Basically, I want to get something like this:
$entities = Entity::with(['attribute.valueable' => function ($query) {
$root = $query->getRootParent();
$query->where('entity_id', $root->id);
}])->get();
SQL-queries should be like
select * from `entities`;
select * from `entity_types_attributes` where `entity_types_attributes`.`entity_type_id` in (?);
select * from `entity_attribute_value_int` where `entity_attribute_value_int`.`attribute_id` in (?, ?, ?)
AND `entity_attribute_value_int`.entity_id` = ? // this part should be appended

Controller sends null value in a set command in Symfony2

I have a controller that inserts new records, but sends NULL value to idUsuario which is the ID of the user who is creating the new record.
I have already checked the entity file, the estructure of the table, even setting a manual value like 1. I have tried the sql command directly in mysql command window and the problem in that idUsuario is comming NULL.
Controller:
function createAction ....
$user = $this->getUser();
$idUser = $user->getId();
$entity = new InProveedor();
$entity->setIdUsuario($idUser);
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
Entity:
/**
* #ORM\ManyToOne(targetEntity="Nival\AccesoBundle\Entity\AdUsuario",
inversedBy="proveedorUsuario")
* #ORM\JoinColumn(name="id_usuario", referencedColumnName="id_usuario")
*/
protected $proveedorUsuario;
/**
* #var integer
*
* #ORM\Column(name="id_usuario", type="integer", nullable=false)
*/
private $idUsuario;
/**
* Set idUsuario
*
* #param integer $idUsuario
* #return InProveedor
*/
public function setIdUsuario($idUsuario)
{
$this->idUsuario = $idUsuario;
return $this;
}
/**
* Get idUsuario
*
* #return integer
*/
public function getIdUsuario()
{
return $this->idUsuario;
}
An exception occurred while executing 'INSERT INTO in_proveedor (razon_social, nombre_comercial, direccion, telefono, email, nrc, nit, contacto, fecha_ingreso, id_forma_pago, dias_entrega, id_aut1_asig, id_notificado, fecha_notificado, id_aut1, fecha_aut1, id_categoria, id_usuario, fecha_creado, activo, id_empresaa) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' with params ["GM Consulting SA de CV", "GM Consulting SA de CV", "9 Calle poniente 81 Ave norte col Escal\u00f3n 7-29, San Salvador", "22875000", "gmccapacitaciones2019#gmail.com", "22222", "222", "Astrid Cuadra", "2019-05-28", 1, null, 1, null, null, null, null, 1, null, "2019-05-28 20:50:41", 0, "2"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id_usuario' cannot be null
So, it seems that even if I set a value for field idUsuario, it always return as NULL. Please help me out.
Well, what I did it was so weird, I had to remove the relationship beteewen tables, and save a record with the ID, then I put back the relationship in the entity files (both: AdUsuario and InProveedor) and it worked properly.

belongsToMany multiple foreign keys, laravel

Good morning
I currently have a table that is related to 3 tables.
It has occurred to me to do "belongsToMany", but I do not know how to do it with 3 relationships
Tables:
schools_series (relation)
id
cycle_id
school_id
serie_id
cycle
id
active (true / false)
** more columns **
school
id
** more columns **
serie
id
** more columns **
Principal Model:
School
class School extends Model implements Presentable
{
use PresentableTrait;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'network_id',
'fantasy_name',
'social_name',
'email',
'sim_web_code',
'state_registration',
'cnpj',
'status',
'start_date',
];
public function series()
{
return $this->belongsToMany(Serie::class, 'schools_series')->where('id_cycle', 'xxxx');
}
I need to be able to take out the "school series" depending on the "cycle_id" that has "active" in cycle
example SQL:
SELECT ss.* FROM schools as s
INNER JOIN schools_series as ss
ON ss.school_id = s.id
INNER JOIN cycle as c
ON ss.cycle_id = c.id AND c.active = 1
WHERE s.id = 115
Solution:
public function series()
{
return $this->belongsToMany(Serie::class, 'schools_series')->withPivot('cycle_id')->join('cycle', 'cycle.id', '=', 'schools_series.cycle_id')->where('cycle.active', '=', 1);
}

Laravel - hasManyThrough with Limit/Take

I have Products, SubCategories, Categories relationship..
in Category model where I defined hasManyThrough relationship :
public function products()
{
return $this->hasManyThrough('Products','SubCategory');
}
How do I display only 4 products on each category?
$products = Category::with('products')->get()
I already add take(2) or limit(2) on hasManyThrough relationship, but the query limit overall products, not by subcategory. Here is the query log :
select products.*, subcategories.category_id from products inner join subcategories on subcategories.id = products.subcategory_id where subcategories.category_id in (?, ?, ?, ?, ?, ?) limit 4
I dont't think you can set hasManyTrough relation limits, but you can separate your relations and set own limits for them:
Category has subcategories:
public function subcategories()
{
return $this->hasMany('Subcategory')->limit(2);
}
Subcategories has products:
public function products()
{
return $this->hasMany('Product')->limit(4);
}
Then you can call:
Category::with('subcategories.products')->get();

Does Eloquent ORM change CamelCase to underscores?

Im getting an error in Laravel using Eloquent which is:
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'task_manager.rel_developers_projects' doesn't exist (SQL: insert into
`rel_developers_projects` (`project_id`, `developer_id`, `updated_at`, `created_at`)
values (?, ?, ?, ?)) (Bindings: array ( 0 => '1', 1 => '1', 2 => '2013-07-31 08:23:35', 3
=> '2013-07-31 08:23:35', ))
However, the Model is called RelDevelopersProject and the table is called RelDevelopersProjects.
Does Eloquent try to convert CamelCased names to underscores?
Do not use camel case for table names.
If you however need to, try this:
class RelDevelopersProject extends Eloquent {
protected $table = 'RelDevelopersProjects';
}
See eloquent in the Laravel Docs.
Yes, it does.
Just define the table name as a property in Model
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'RelDevelopersProject';

Resources