I have 2 tables:
articles
id | title | category_id | created_at | updated_at |
and categories
id | name | descriptions | created_at | updated_at |
Relations : category hasMany-> articles and articles belongsTo -> category.
how simple way make query something like :
public functions getArticles ($category) {
$articles = Articles::where('category', '=', $category);
}
In documentations exist example with Id (http://laravel.com/docs/4.2/eloquent#one-to-many ) , but I want select articles, knowing name category.
How in query specify condition with relations ?
If exist such methods, please help me.
Thanks ;)
You can use whereHas method. Like:
$articles = Articles::whereHas('category', function($query)use($category){
$query->where('name', $category->name);
});
I suppose that should work. Or you can just create a scope and join categories table and then check by it.
Related
One to many relationships, each product has many prices
table products
id | name | slug | created_at | update_at
table prices
id | product_id | title | price | link
I want to get the data limit of product limit 20 table and order created_at and each product get the lowest price, order column price. I want to use the query builder.
i tried
$products = DB::table('products')
->leftJoin('prices', 'products.id', '=', 'prices.product_id')
->select('products.id', 'products.name')->distinct()
->selectRaw('max(prices.price) as price')
->groupby('products.id')
->orderby('products.updated_at')
->get();
but it get all products and table prices order column id
You can use Eloquent Like This
public function price() {
return $this->hasMany('App\model\Prices' , 'product_id' ,'id');
}
and get like this , It will give you the mapped price only for your specific product
$product = Product::with('price')
->where(do the stuffs)
->orderBy(do the stuffs)
->get();
Or you can use the callback as well in with()
i am having some trouble getting results from a query. it's the following. I have two tables, tasks and task_interactions. the table tasks stores the tasks, and the table task_interactions stores the history of the tasks, like a change of status, comments... The column task_id in the task_interactions table is the id in the table tasks.
The table tasks has the following columns: id | project_id | task_type_id | related_block | created_by | assigned_to | start_date | due_date | task_priority | comments | status | created_at |updated_at The status in this table will be deleted.
The table taskinteractions has the following columns:
id,task_id,status,comments,created_at
In the models i have created the following relationships:
Task Model:
public function taskinteractions()
{
return $this->hasMany('App\Taskinteraction');
}
Taskinteraction Model:
public function tasks()
{
return $this->belongsTo('App\Task');
}
And now the question:
I want to get all the tasks assigned to the authenticated user with status (in the table taskinteractions) equal to "In Progress".
I have tried a lot of different approaches with no good results.
I am a newbie and so i believe that the solution might be simple, but i no idea how to do it.
Assuming assigned_to has the id of the user and a typical user table, try the following,$tasks is the array of tasks you want to get
$interactions = TaskInteractions::where('status','In Progress')->get();
$tasks = array();
foreach($interactions as $interaction){
$task = $interaction->task;
if((!(in_array($task, $tasks))) && (Auth::user()->id == $task->assigned_to) ){
array_push($tasks,$task);
}
I am trying to run join between my pages table and users table. Means one user can create multiple pages and in pages table created_by column belongs to my users table column id.
Table Structure:
---------------------------------------------
id | page_title | page_desc | created_by |
---------------------------------------------
1 | Testing | Descripti | 1 |
---------------------------------------------
2 | New Page | Desc | 2 |
User table
-------------------------------------------
id | name | email | pass | created_at |
-------------------------------------------
1 | A | a#g.c | 123 | 2017-10-21 |
-------------------------------------------
2 | B | b#g.c | 123 | 2017-10-21 |
in my Page model i used:
public function createdBy(){
return $this->belongsTo('App\User','created_by','id');
}
now when i am trying to get the data with:
$model = Page::all()
foreach($model as $key => $value){
echo $value->createdBy->name."<br/>";
}
laravel generating multiple queries to get name of each user is that any way to run the join instead of multiple queries?
You're running into the N+1 problem. You need to eager load your relationship to resolve this. You can read more on eager loading here.
Use the with() method on the page query to eager load all the related user records for each page:
$model = Page::with('createdBy')->get();
foreach ($model as $key => $value) {
echo $value->createdBy->name."<br/>";
}
This will now only run 2 queries: one to get all the pages, and one to get all the users related to each page.
For that reason Laravel provides eager Loading
Eager Loading
When accessing Eloquent relationships as properties, the relationship data is "lazy loaded". This means the relationship data is not actually loaded until you first access the property. However, Eloquent can "eager load" relationships at the time you query the parent model
For more info just check this link.
OR Just Use Laravel's database query builder
You can perform join directly on your Table and fetch directly the data
$users = DB::table('pages')
->join('users', 'pages.created_by', '=', 'users.id')
->select('users.name','users.email', 'pages.*') //Specify what parameters you want.
->get();
To Join queries you can use laravel query builder like below
$pages = DB::table('pages')
->join('users', 'pages.created_by', '=', 'users.id')
->select('users.*', 'pages.*')
->get();
I'm having trouble defining a relationship in Eloquent. I have two tables.
The first table contains email domains. Here is an example:
+-------+----------------+-----------+
| ed_id | ed_domain | ed_isp_id |
+-------+----------------+-----------+
| 17 | | 6 |
| 13 | aim.com | 1 |
| 12 | aol.com | 1 |
+-------+----------------+-----------+
The second table contains information about my users, one of the columns being an email address.
I have tried to set this up using...
public function users()
{
return $this->hasMany('Leadgen\Lead', \DB::raw('SUBSTRING_INDEX(l_email, \'#\', -1)'), 'ed_domain');
}
What I expected to happen is something like the following:
LEFT OUTER JOIN email_domains ON SUBSTRING_INDEX(email, '#', -1) = ed_domain
What I receive though is a SQL error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'leads.SUBSTRING_INDEX(l_email, '#', -1)' in 'where clause' (SQL: select * from `leads` where `leads`.`SUBSTRING_INDEX(l_email, '#', -1)` in (aol.com))
You cannot use the standard Laravel relations as they require to have related tables having foreign keys paired to primary keys. What you can do is to do the LeftJoin using query builder and return the users manually.
public function users() {
return DB::table('users as u')
->leftJoin('email_domains as ed', DB::raw('SUBSTRING_INDEX(u.email, \'#\', -1)'), '=', 'ed.ed_domain')
->select('u.*');
}
This function will return query builder object so you can do further chaining according to your requirements and finally use ->get() to have the final result. I have not actually run the code but basically this is what you need to do.
I'm simply trying to join 2 tables with Laravel 4's Eloquent ORM. The tables are:
TABLE: PRODUCTS
ID | CATEGORY_ID | NAME
-------------------------
1 | 2 | Hammer
2 | 2 | Saw
3 | 1 | Apple
TABLE: CATEGORIES
ID | NAME
-----------
1 | Food
2 | Tools
Of course this can be done with SQL:
SELECT products.name, categories.name
FROM products
INNER JOIN categories ON products.category_id = categories.id
And this will output:
Hammer | Tools
Saw | Tools
Apple | Food
But is there an easier way to get the same result using Laravel's Eloquent, maybe using the build-in table relationships?
Set up a many-to-one relation in your models:
Category.php
public function products() {
return $this->hasMany('Product');
}
Product.php
public function category() {
return $this->belongsTo('Category');
}
Then call:
$products = Product::with('category')->get();
For each element of the result, $products->name and $products->category->name will contain your fields.