I'm using laravel with eloquent and I want to create a table (php) with specification for some products, like this
Models | ModelA | ModelB |
Size | 234 | 321 |
Sensitivity | 21 | - |
Temperature | 23 |
And my DB tables :
Models:
idModel | nameModel
1 | ModelA
2 | ModelB
Specs:
idSpec | titleSpec | spec | idModel
1 | Size | 234 | 1
2 | Size | 321 | 2
3 | Sensitivity | 21 | 1
4 | Temperature | 23 | 1
5 | Temperature | 23 | 2
So I want to create the table with some rules:
I want to organize it by model and by titleSpec
can't repeat the titleSpecs
if ModelA has one specific titleSpec and ModelB doesn't, it gets an '-'
if Model B and Model A has same value in the titleSpec, it gets an colspan with the value!
I'm using eloquent relationships!
My only problem is how to build this; should I change the DB structure?
This is not a job for the model! Your controller needs to organize and prepare the data for the view.
Related
I'm thinking over to design an API to filter objects using fos_rest bundle in Symfony2 and Doctrine with MySQL.
Let's say I have a Master Entity, which has relations with different entities which have some properties.
Now in frontend I would like to create a filter, where one can filter the Master Entity by the properties of the related Entities. How would that be doable?
say we have
+---------------+
| Master Entity |
+----+----------+
| id | name |
+----+----------+
| 1 | Apple |
+----+----------+
| 3 | Berry |
+----+----------+
+-------------------+
| Property Entity |
+----+------+-------+
| id | id_m | value |
+----+------+-------+
| 1 | 1 | green |
+----+------+-------+
| 2 | 1 | yello |
+----+------+-------+
| 3 | 1 | red |
+----+------+-------+
| 4 | 3 | pink |
+----+------+-------+
And I want to have a filter, where I filter by the values in Property Entity
I would like to do something like
$em->getRepository('AcmeBundle\MasterEntity')->findBy(array("PropertyEntity:value" => "red","PropertyEntity:value" => "yello"))
so it would return the object collection of Master Entity with ID=1 (apple) - because both parameters would match Apple
You can create a query builder instead of use findBy
$qb->select('m')
->from('AcmeBundle\MasterEntity', 'm')
->join('m.PropertyEntity', 'p')
->where('p.value IN (:values)')
->setParameter('values',['red','yellow']);
I'm having an issue with writing an eloquent query for a search function in my project.
Here are my database tables/models:
artist
| id | name |
---------------------
| 1 | Van Gogh |
| 2 | Michelangelo |
art
| id | title |
---------------------
| 1 | David |
| 2 | Starry Night |
art_artist
| id | art_id | artist_id |
---------------------------
| 1 | 1 | 2 |
| 2 | 2 | 1 |
style
| id | title |
---------------------
| 1 | Sculpture |
| 2 | Painting |
art_style
| id | art_id | style_id |
--------------------------
| 1 | 1 | 1 |
| 2 | 2 | 2 |
One artist hasMany art pieces, one art piece hasMany styles, and also hasMany artists. I have verified that the relationships work correctly. I also have a simple form that returns ids as a GET request with the variables artist and style.
So, I want to do two things in my function: First, check if the variables in the request are set (I can already do this). Then, USE ELOQUENT to query the art model based on the results of the form.
Here's an example: A user searches for a Sculpture by Michelangelo. The function queries the art database for any piece that is a sculpture by michelangelo and returns it as an art model.
The trouble is, I have absolutely no idea how to query the database based on the id of a related model. Any ideas?
I finally figured out how to do the query. First, I have to tell Eloquent I want to retrieve the artist model along with the art, THEN I can use whereHas:
$art = Art::with('artists')->whereHas('artists',function( $query ){
$query->where('artists.id',1);
})->get();
I'm trying to figure out the best way to retrieve results from the database such that the created_at is the most recent, and also checking that another value (in this case Temps->value) matches a specific criteria..
For example (some information abbreviated)
LOCATIONS
+----+---------+
| ID | CITY |
+----+---------+
| 1 | DALLAS |
| 2 | CHICAGO |
| 3 | ATLANTA |
+----+---------+
TEMPS
+----+-------+----------+------------+
| ID | VALUE | CITY_ID | CREATED_AT |
+----+-------+----------+------------+
| 1 | 70 | 1 | 2010 |
| 2 | 95 | 1 | 2015 |
| 3 | 90 | 2 | 2010 |
| 4 | 80 | 2 | 2015 |
| 5 | 99 | 3 | 2015 |
+----+-------+----------+------------+
my location model.
class Location extends model
{
...
public function latestValue()
{
return $this->hasOne('App\Temp')->latest();
}
In this case I would only like the Locations in which the latest temperature reading is > 90..
In my controller if have
$highTemps = Location::with('latestValue')->get();
without iterating through every city explicitly, is there a way to adjust my eloquent relationship, or even use a collection method to filter the results?
I've looked at filter() but I'm not sure how to use that on a relationship. Especially if you're trying to filter 2-3 relationships deep. (imagine I'm starting off with Country->states->locations->temps->latestValue etc)
It would be great to have the initial query filter the results. But I can't figure out the combination of groupBy() and max() and having() etc to make the eloquent statement work.
I think the Relationship you are establishing, it's wrong..
The Problem is very simple if the relationship hasMany() will be used..
First all the latest entries will be fetched , followed by filtering the max out of them.
class Location extends model
{
...
public function latestValue()
{
return $this->hasMany('App\Temp')->latest();
}
rest is not that much typical i assume.
Okay so I'm creating a task manager for my company. A user can assign assign a task to multiple other users. So I've though of 2 ways of implementing this.
This is my tasks table for option one (at least the columns that are important in this discussion ):
----------------------------------------------
| id | assigned_to | assigned_from |
---------------------------------------------
| 1 | 1,3,6 | 4 |
--------------------------------------------
| 2 | 1,4 | 2 |
---------------------------------------------
So here I pretty much just comma separate each user_id that is assigned to this particular task
Option 2:
----------------------------------------------------------
| id | task_id | assigned_to | assigned_from |
------------------------------------------------------------
| 1 | 335901 | 1 | 4 |
-----------------------------------------------------------
| 2 | 335901 | 3 | 4 |
-----------------------------------------------------------
| 3 | 335901 | 6 | 4 |
-----------------------------------------------------------
| 4 | 564520 | 1 | 2 |
-----------------------------------------------------------
| 4 | 564520 | 4 | 2 |
-----------------------------------------------------------
So as you can see here instead of putting the assiged_to is's here I just create a task id which is a random number and then I can groupBy 'task_id'. This is currently they way I have built it but for some reason it feels like it might screw me over in the future (not that option one doesn't give me the same feeling). So my question is which way do you guys recommend or is there maybe a different better way that I could be doing this?
Option 2 ist the better solution since you can acutally work with the table. You may e.g. create another table Tasks with
Task_id | Task_name | Budget | ...
Or a table with user-IDs for assigned_to and assigned_from. All these tables can be joined together if you use 2nd Option.
btw it is the correct normalization form
You can use Option 2 and normalize further if tasks are always assigned by/from the same person.
Tasks table:
task_id | assigned_from
1 | 4
2 | 2
The Assignees table then doesn't need to have the assigned_from since it's always the same for that task_id:
id | task_id | assigned_to
1 | 1 | 1
2 | 1 | 3
3 | 1 | 6
4 | 2 | 1
5 | 2 | 4
So, i have three tables
Table: Users
_________________
| id | user |
-------------------
| 1 | Roy |
| 2 | Ben |
|________|________|
Table: Hability_lists // Where i set the list with all habilities available
___________________________________
| id | category | subcategory |
------------------------------------
| 1 | Programmer | PHP |
| 2 | Programmer | ASP |
|________|____________|_____________|
Table: Habilities // Where i set the habilities from all users
________________________________________
| id | user_id | hability_list_id |
-----------------------------------------
| 1 | 2 | 1 |
| 2 | 1 | 2 |
|________|____________|__________________|
By this, we can see that:
Roy are a ASP Programmer and Ben are a PHP Programmer
But, how to set relative models like this using CakePHP?
I know how by using two models but not using three models.
There is some way to do this? Or maybe a better way to do?
Thanks in advance.
When working with an MVC framework it's highly recommended to follow its conventions. So a few changes may be beneficial for you.
What you are looking for its the HABTM (Has And Belongs To Many) association between the "users" table and the "habilities" table *. I'm guessing, by the design of your table, that a user can have multiple habilities, otherwise you should check the hasMany association.
It should be something like this:
Table habilities:
select * from habilities;
+----+------------+----------------------+----------+
| id | category | subcategoy | created | modified |
+----+------------+------------+---------+----------+
| 1 | Programmer | ASP | | |
| 2 | Programmer | PHP | | |
| 3 | Musician | Classical | | |
+----+------------+------------+---------+----------+
Table users:
select * from users;
+----+-------+---------------------+---------------------+
| id | name | created | modified | **
+----+-------+---------------------+---------------------+
| 1 | Roy | 2012-08-15 02:52:18 | 2013-01-17 03:25:28 |
| 2 | Ben | 2012-11-10 03:36:12 | 2012-11-10 03:36:12 |
+----+-------+---------------------+---------------------+
Relational table for HABTM:
select * from habilities_users;
+----+-------------+-------------------+----------+
| id | hability_id | user_id | created | modified |
+----+-------------+---------+---------+----------+
| 1 | 1 | 2 | | |
| 2 | 2 | 1 | | |
+----+-------------+---------+---------+----------+
Look the reference columns in habilities_users, they're singular with a _id suffix to work with CakePHP.
Defining the models classes it's also important, since it's where you define all their associations.
app/Model/User.php
<?php
class User extends AppModel {
public $hasAndBelongsToMany = array('Hability');
}
app/Model/Hability.php
<?php
class Hability extends AppModel {
public $hasAndBelongsToMany = array('User');
}
The table habilities_users doesn't need a model file, its behaviours and properties are implicit in the declaration of its associated models.
* using those names it's also the CakePHP way. [link]
** adding "created" and "modified" in each table will store those events for each record automatically.
You'll want to use HasAndBelongsToMany (HABTM).
This allows you to have two models - User and Hability that are joined by a "tweener" table.