I have two models User and Address, one user can have many addresses but I want to fetch only which is primary(where primary=true)
this is what I have tried, and I am getting multiple users in the list
$users = User::join('addresses', 'addresses.user_id', 'users.id')
->select('name','phone_number','address','landmark','city','state','pincode','users.status')
->get();
I tried this too but I am not getting any data
$users = User::join('addresses', 'addresses.user_id', 'users.id')
->where('addresses.primary', true)
->select('name','phone_number','address','landmark','city','state','pincode','users.status')
->get();
thank you
Collection {#375 ▼
#items: array:8 [▼
0 => User {#376 ▶}
1 => User {#377 ▼
#attributes: array:9 [▼
"name" => "Colin Sushanth"
"phone_number" => "9987217545"
"address" => "2nd Cross 3rd street, y this is my address"
"landmark" => "Near the address"
"city" => "Mangalore"
"state" => "Karnataka"
"pincode" => 575002
"status" => "valid"
"primary" => "true"
]
}
2 => User {#378 ▶}
]
}
You should try this:
$users = User::join('addresses', 'addresses.user_id', 'users.id')
->where('addresses.primary','=',1)
->select('name','phone_number','address','landmark','city','state','pincode','users.status')
->get();
Or:
$users = User::join('addresses', 'addresses.user_id', 'users.id')
->where('addresses.primary','=',true)
->select('name','phone_number','address','landmark','city','state','pincode','users.status')
->get();
Updated answer
Blade file:
#if(isset($users))
#foreach($users as $user)
#if($user->primary === 'true')
//Your code
#endif
#endforeach
#endif
I would do it using eloquent models
So you would u do
User::whereHas('primary')->pluck('name','phone_number','address','landmark','city','state','pincode','users.status')
and your model will look like this
public function addresses()
{
return $this->belongsTo('App\Models\Address');
}
public function primary()
{
return $this->addresses->primary == true;
}
Related
unable to delete all nested branches where "product" => null
Have a query
$cartWhere['user_id'] = $user_id;
$cartWhere['site_id'] =$currentSite->id;
$item = Cart::select('product_id','quantity')->with(['product' => function($product) use ($search){
$product->join('product_translations', 'products.id', '=', 'product_translations.product_id');
$product->where( 'product_translations.name', 'LIKE','%'.$search.'%');
},'product.manufacturer:id,name'])
->where($cartWhere)->get();
then I receive collection that has all filtered carts but some of these carts have a relation with product => null
1 => App\Models\Cart {#736 ▼
...
#original: array:2 [▼
"product_id" => 1
"quantity" => 2
]
...
#relations: array:1 [▼
"product" => App\Models\Product {#785 ▶}
]
}
2 => App\Models\Cart {#736 ▼
...
#original: array:2 [▼
"product_id" => 2
"quantity" => 2
]
...
#relations: array:1 [▼
"product" => null
]
}
sorry for my English
You can filter them from the results using the collections filter() method
$item = Cart::select('product_id','quantity')
->with(['product' => function($product) use ($search) {
$product->join('product_translations', 'products.id', '=', 'product_translations.product_id');
$product->where( 'product_translations.name', 'LIKE','%'.$search.'%');
}, 'product.manufacturer:id,name'])
->where($cartWhere)
->get()
->filter(function ($cart) {
return $cart->product !== null;
});
Along with with you should use whereHas. So the result will not include any relation with null value. So this way you can also avoid the extra filter method used.
I have 2 tables :
Valuechains : id, created_at, updated_at, deleted_at
Segments : id, valuechain_id (Foreign key), created_at, updated_at, deleted_at
And pivot tables (not really important here).
I have a method with sql requests ...
$valuechains list gives me a list of all the value chains which are not (soft) deleted
$valuechainCount counts the number of valuechains which are published
$segmentCount counts the number of segments for each value chains
I try to use the map function in order to add a column which contains the number of segments for each value chains ...
public function vcListAndSegmentCount() {
$valuechainLists = Valuechain::select('valuechains.id', 'lang_valuechain.vcname', 'lang_valuechain.vcshortname')
->join('lang_valuechain', 'valuechains.id', '=', 'lang_valuechain.valuechain_id')
->join('langs', 'lang_valuechain.lang_id', '=', 'langs.id')
->where('langs.isMainlanguage', '=', '1')
->whereNull('valuechains.deleted_at')
->get();
$valuechainCount = Valuechain::whereNull('valuechains.deleted_at')->count();
for ($i=0; $i < $valuechainCount; $i++) {
$segmentCount[$i] = Segment::whereNull('segments.deleted_at')
->where('valuechain_id', '=', $valuechainLists[$i]->id)->count();
}
$valuechainLists = $valuechainLists->map(function ($record) use ($segmentCount) {
$vclists = array_first($segmentCount, function ($value, $key) use ($record) {
return $value['id'] === $record['valuechain_id'];
});
$record['count'] = $vclists;
return $record;
});
dd($valuechainLists);
}
The map methods adds a column my output collection. Unfortunatelly, the new collection is not giving me the right numbers of segments for each value chain... it only adds one value ...
Here is what I obtain :
Collection {#380 ▼
#items: array:4 [▼
0 => Valuechain {#450 ▼
...
#attributes: array:4 [▼
"id" => 1
"vcname" => "Génétique"
"vcshortname" => "Génétique"
"count" => 6
]
#original: array:3 [▶]
...
}
1 => Valuechain {#451 ▼
...
#attributes: array:4 [▼
"id" => 2
"vcname" => "Biotruc"
"vcshortname" => "Biotruc"
"count" => 6
]
...
}
2 => Valuechain {#452 ▼
...
#attributes: array:4 [▼
"id" => 3
"vcname" => "VC3"
"vcshortname" => "VC3"
"count" => 6
]
...
}
3 => Valuechain {#453 ▼
...
#attributes: array:4 [▼
"id" => 4
"vcname" => "VC4"
"vcshortname" => "VC4"
"count" => 6
]
#original: array:3 [▶]
...
}
]
}
I obtain 6, 6, 6 and 6 whereas the count should be 6, 5, 4, 4...
If you are using Laravel >= 5.2 and if you have defined the relationships on the models, you can use the withCount() method.
It would go something like this:
Valuechain::select('valuechains.id', 'lang_valuechain.vcname', 'lang_valuechain.vcshortname')
->withCount(['segments' => function ($query) {
$query->whereNull('deleted_at);
}])
->join('lang_valuechain', 'valuechains.id', '=', 'lang_valuechain.valuechain_id')
->join('langs', 'lang_valuechain.lang_id', '=', 'langs.id')
->where('langs.isMainlanguage', '=', '1')
->whereNull('valuechains.deleted_at')
->get()
or if your Segment model uses the SoftDeletes trait, then it's a bit simpler:
Valuechain::select('valuechains.id', 'lang_valuechain.vcname', 'lang_valuechain.vcshortname')
->withCount('segments')
->join('lang_valuechain', 'valuechains.id', '=', 'lang_valuechain.valuechain_id')
->join('langs', 'lang_valuechain.lang_id', '=', 'langs.id')
->where('langs.isMainlanguage', '=', '1')
->whereNull('valuechains.deleted_at')
->get()
add count value as a property instead of array element.
$valuechainLists = $valuechainLists->map(function ($record) use ($segmentCount) {
$vclists = array_first($segmentCount, function ($value, $key) use ($record) {
return $value['id'] === $record['valuechain_id'];
});
$record->count = $vclists;
return $record;
});
I changed
$record['count'] = $vclists;
to
$record->count = $vclists;
Add a reference: &$segmentCount
$valuechainLists = $valuechainLists->map(function ($record) use (&$segmentCount) {....
Also I'm not sure what your array_first function is doing.
I want to show only one result from "links, tags, pages", "->first()", but, I want to show multiple results from "comments", "->get()", separate it in one array, and send to view, how can I do this?
$link = DB::table('links')
->join('tags', 'tags.id', 'links.tag')
->join('pages', 'pages.id', '=', 'links.page_id')
->leftJoin('comments', 'comments.link_id', '=', 'links.id')
->select('links.photo', 'links.id', 'links.description', 'links.country', 'links.url', 'links.suggestions', 'links.shares', 'links.friendly_url', 'links.page_id', 'links.sponsored', 'links.clicks', 'links.title', 'tags.color', 'tags.id as tag_id', 'tags.name', 'pages.name as p_name', 'pages.description as p_description', 'pages.id as p_id', 'pages.followers', 'pages.links', 'pages.friendly_url as p_friendly_url', 'pages.photo as p_photo')
->where('links.friendly_url', $id)
->first();
return view('site.link', compact('link'));
DD($link);
0 => Link {#291 ▼
#relations: array:3 [▼
"page" => Page {#295 ▶}
"tag" => Tag {#289 ▶}
"comments" => Collection {#292 ▼
#items: array:2 [▼
0 => Comment {#299 ▶}
1 => Comment {#301 ▶}
]
}
]
You could use Eloquent. Define relationships:
public function page()
{
return $this->belongsTo(Page::class);
}
public function tag()
{
return $this->belongsTo(Tag::class, 'tag');
}
public function comments()
{
return $this->hasMany(Comment::class);
}
And do this:
Link::with('page', 'tag', 'comments')->where('friendly_url', $id)->first()
This query returns all groups with an id however it also returns all the products to every group.
$groups = \App\Group::where('campaign_id', $id)->with('product')->get();
dd($groups->toArray());array:2 [▼
This is the output.
0 => array:6 [▼
"id" => 24
"campaign_id" => "TRE36934"
"group_name" => "group2"
"created_at" => "2017-05-17 16:14:55"
"updated_at" => null
"product" => array:4 [▼
0 => array:8 [▶]
1 => array:8 [▶]
2 => array:8 [▶]
3 => array:8 [▶]
I am trying to return the groups with same id. Can I somehow query? The join in the id in the groups table and the foreign key in call 'group' in the group table.
A simple inner join should suffice here, right?
$groups = \App\Group::join('product', 'group.campaign_id', '=', 'product.group')
->where('group.campaign_id', $id)
->get();
try :
$groups = Group::join('product', 'group.campaign_id', '=', 'product.group')
->where('group.campaign_id', $id)
->get();
If you want to get your product with the same campaing id, you can do the following :
$products = Product::get()->groupBy('campaign_id');
Or you can do it directly from SQL
So, if you want a collection of Product, use your product model :)
I'm not sure but you may try this:
$group = \App\Group::where('campaign_id', $id)->get();
$group->load('products');
Thanks for all your replies they all got me a bit cloer
$products = \App\Product::join('groups', 'groups.id', '=', 'products.group')->get()->groupBy('group');
The basic groupby by Mathieu Ferre got me close. I added a join with a groupby as suggested by Mozammil on the name to give me
$products = \App\Product::join('groups', 'groups.id', '=', 'products.group')->get()->groupBy('group_name');
I'm currently using jenseggers-mongodb eloquent in laravel 5 with mongodb 3.0.3.
I'm trying to join two different tables as follows:
User Model
public function userpayment() {
return $this->hasMany('App\Models\Userpayment', 'user_id', '_id');
}
Userpayment model
public function user() {
return $this->belongsTo('App\Models\User','user_id');
}
I'm using repository pattern
public function __construct() {
$this->model = new User;
}
return $this->model->with(array('userpayment'=>function($query){
$query
->groupBy('dealCodeNumber')
->get();
}))
->where('_id',$sid)
->get();
groupBy dealCodeNumber returns NULL.
array:1 [▼
0 => array:15 [▼
"_id" => "55813f4cbc59a3f1372e9e6f"
"full_name" => "Varathan"
"username" => "shopsyadmin"
"web_url" => ""
"userpayment" => []
]
without groupby returns all.
array:1 [▼
0 => array:15 [▼
"_id" => "55813f4cbc59a3f1372e9e6f"
"full_name" => "Varathan"
"username" => "shopsyadmin"
"userpayment" => array:2 [▼
0 => array:57 [▼
"_id" => "55816ce7cc7d4bac0d000029"
"dealCodeNumber" => "1398410837"
"inserttime" => "1398411401"
"status" => "Pending"
]
1 => array:57 [▶]
]
Querylog with groupby
[query] => shopsy_user_payment.aggregate([{"$match":{"user_id":{"$in":["55813f4cbc59a3f1372e9e6f"]}}},{"$group":{"_id":{"dealCodeNumber":"$dealCodeNumber"}
Why groupby returns null?
To group an column it must be selected before grouping. Changing code to below works:
return $this->model->with(array('userpayment'=>function($query){
$query
->select('product_id','user_id','dealCodeNumber')
->groupBy('dealCodeNumber')
->get();
}))
->where('_id',$sid)
->get();