Return selective rows Laravel Eloquent - laravel

I want to filter product using their attributes using below query
return Product::with('attributes')
->whereHas('attributes', function ($query) use ($attribute_id_array,$attribute_value_array){
for($k=0;$k<count($attribute_id_array);$k++)
{
$attr_id=$attribute_id_array[$k];
$attr_val=$attribute_value_array[$k];
$query->where(function($q) use ($attr_id, $attr_val) {
$q->where('attribute_id', $attr_id)->where('value', $attr_val);
});
}
})->paginate(10);
I want to check if attributes of a product exist then filter it using the loop to filter out products that are in attributes_value & attributes_id array which does not match but presently this query is not filtering through attributes.
Here are the structure of tables and relations
Product Table :
|id | Title | Price|
-------------------------
|1 | Title 1 | 5000|
|2 | Product 2 | 7000|
and the other is
product_attribute table:
|id | product_id | attribute_id | attribute_name | value|
---------------------------------------------------------
|1 | 1 | 5 | Color | Red |
|2 | 1 | 6 | Size | XL |
|3 | 2 | 5 | Color | Green|
Product and Product attribute is related with following relation (In the product model):
public function attributes()
{
return $this->hasMany(ProductsAttribute::class, 'product_id ');
}

I believe you need to validate each attribute and value combinations to be present for the resultant products, so you can put your whereHas clause inside the loop as
$products = Product::with('attributes');
for($k=0; $k<count($attribute_id_array); $k++)
{
$attr_id=$attribute_id_array[$k];
$attr_val=$attribute_value_array[$k];
$products->whereHas('attributes', function ($query) use ($attr_id,$attr_val){
$query->where('attribute_id', $attr_id)->where('value', $attr_val);
});
}
$products = $products->paginate(10);

Related

Eloquent model relationship for final table

I've the following tables
Cities (City model)
+----+-------+
| id | name |
+----+-------+
| 1 | tokyo |
+----+-------+
events (Event model)
+----+--------------------+---------+
| id | title | city_id |
+----+--------------------+---------+
| 1 | Biggest event ever | 1 |
+----+--------------------+---------+
event_user_applications (EventUserApplication model)
+----+----------+---------+
| id | event_id | user_id |
+----+----------+---------+
| 1 | 1 | 1 |
+----+----------+---------+
How do I get the city on EventUserApplication model.
I tried both of this in the EventUserApplication
public function city()
{
// return $this->belongsTo('App\Model\City', 'city_id')->using('App\Model\Event', 'event_id');
// return $this->hasOneThrough('App\Model\City', 'App\Model\Event', 'city_id', 'id');
}
Can't get any of this to work. Already spent hours. Please help. Thank you in advance.
I solved it with the help of my friend. This is what I did to get the city.
$applications = EventUserApplication::with(
'user:id,name,phone,email,date_of_birth',
'event:id,title,area_id,area_city_id',
'event.city' // nester eager loading
)->latest()->get();
In the Event model, I already had this
public function city()
{
return $this->belongsTo('App\Model\City', 'area_city_id');
}
It's the Nester Eager Loading which was needed.
In that case you can use hasOnThrough relationship EventUserApplication has One city Through Event.
Edit:The 5th parameter should be event_id and there should be another parameter which is id (foreign key of event table)

WhereIN data for calculations for displaying results

I am trying to work out the best practice to calculate Avg Attendance.
I would like to show this on the Member View (html part is no issue)
I have the following 3 databases
Members DB
|id|first|last|..........
|1 |.....................
|2 |.....................
Rolls DB
|id|roll_id|member_id|status|
|1 |1 |1 |P |
|2 |1 |2 |V |
|3 |2 |1 |A |
|4 |2 |2 |C |
Rollmappings DB
|id|roll_date |roll_year|
|1 |2019-03-01|2019 |
|2 |2019-03-02|2019 |
I have the following in my Member Model
public function roll()
{
return $this->hasMany('App\Roll');
}
I have the following in my Roll Model
public function rollmapping()
{
return $this->hasOne('App\Rollmapping', 'id','roll_id');
}
I would like to count all records which does not equal "A"
So in the code blocks above Member 1 will needs to show me 50% attendance, and member 2 will show me 100% attendance.
I would need to have something in place which will auto roll over when we move into 2020
I do Have Carbon Date installed with the app as well
I got stuck on the link on pulling the year_roll into the select for the Roll and to count I can use:
$rollyear = Rollmapping::lastest()->value('roll_year');
$totalweeks = DB::table('rollmappings')
->where('roll_year', '=', $rollyear)
->get()
->count();
But I am stuck on on pulling the correct records from the roll using the roll_id as I only want the roll_id which have a year date of the current year.
Thanks
If I understand you're question correctly then you should be able to get what you need using whereHas
$count = Roll::whereHas('rollmapping', function ($query) {
$query->whereYear('roll_date', now()->year);
})->count();
If you would also like to exclude all the rolls where the status does not equal A then you would have something like:
$count = Roll::whereHas('rollmapping', function ($query) {
$query->whereYear('roll_date', now()->year);
})
->where('status', '!=', 'A')
->count();

Laravel 4.2 HasMany Relationship using Like

I'm wondering if its possible to set the operator when using a HasMany relationship in Laravel 4.2.
I'm working with a users table and an email log table. The log table has a userID stored in serialised format (as there may be more than one userID stored within the log).
Users table
+---------+
| user_ID |
+---------+
| 1 |
| 2 |
+---------+
emailLog Table
+----+--------------------+
| ID | user_ID |
+----+--------------------+
| 1 | a:1:{i:0;s:1:"2";} |
| 2 | a:1:{i:0;s:1:"1";} |
+----+--------------------+
Am I able to use a hasMany relation with a 'Like' operator rather than an equals operator to return the correct email log ID? Would the statement be written something like the below?
return $this->hasMany('emailLog', 'user_ID', '%user_ID%', 'LIKE');
The proper way to return join table with a where clause would be:
return $this->hasMany('emailLog','user_id')->where('user_id', 'LIKE', '%user_id%');
I found a way to do something similar
class User extends Model
{
public function emailLogs()
{
// old code
// return $this->hasMany(EmailLogs::class, 'user_ID');
// Replace HasMany by like query
return EmailLogs::where('user_ID', 'LIKE', "%{$this->user_ID}%");
}
}

Laravel Categories Map Relationship

I have the following three tables but I don't know how to build a relation between the category and the other data type, in this case 'Page':
posts:
post_id | title | slug
1 | Test | test
2 | Another test | another test
catgory_map:
id | category_id | referrer_id | category_map_type
1 | 2 | 1 | Post
2 | 3 | 2 | Post
3 | 2 | 9 | Page
category
id | name
1 | Laravel
2 | Zend2
3 | Phalcon
So whenever I read a Category I like to be able to do something like this
foreach($category->destinations) ...
I have tried until now with hasManyThrough but it didn't work.
What you have is a many-to-many relation with some additional filtering on the relationship (for the category_map_type). Try this:
Post model
public function categories(){
return $this->belongsToMany('Category', 'category_map', 'referrer_id')
->where('category_map_type', 'Post');
}
Category model
public function posts(){
return $this->belongsToMany('Post', 'category_map', 'category_id', 'referrer_id')
->where('category_map_type', 'Post');
}
Usage
$category = Category::find(1);
foreach($category->posts as $post){
// ...
}
(And the same goes for Post)
You might also want to look into polymorphic many-to-many relations

Laravel multiple whereHas criteria for relationship

I have two tables - contacts and visits:
Contacts Table
id | name
----- | -------
1 | Joe
2 | Sally
Visits Table
id | contact_id | pathname | referrer
----- | ------- | ------- | -------
1 | 1 | about | google
2 | 1 | pricing | null
3 | 1 | signup | null
4 | 2 | about | null
5 | 2 | signup | null
Using eloquent, I would like to retrieve all contacts that have a both a pathname = 'signup' AND a referrer = 'google'.
What I've got so far is:
Contact::whereHas('visits', function($query) {
$query->where('pathname','=','signup');
})
->orWhereHas('visits', function($query) {
$query->where('referrer','=','google');
})
->get();
Which properly retrieves all contacts that have visited either the pricing OR signup page.
However, this example would also retrieve Sally (from the example table above), since she visited signup, but was not referred by google. I need a way to only retrieve Joe, who was both referred by google and visited pricing.
Any ideas? Thanks in advance!
You can use:
Contact::whereHas('visits', function($query) {
$query->where('pathname','=','signup');
})
->whereHas('visits', function($query) {
$query->where('referrer','=','google');
})
->get();
A refined version of the code above:
Contact::whereHas('visits', function($query) {
$query->where('pathname','signup')->where('referrer','google');
})->get();
Several noteworthy points:
You can chain where() clauses within a closure.
The default operator for a where clause is =, so you can omit it.
Use multiple whereHas() clauses, when accessing multiple related models.

Resources