Laravel query is not working with multiple IDs - laravel

I am trying to fetch multiple rows of selected IDs from db. Here is my controller code
$products = new product;
$products = $products->select('products.*', 'categories.category_name')->join('categories', 'products.product_category', '=', 'categories.id');
$products = $products->whereIn('products.id', [$request->list]); //$request->list is post value (12,13)
$products = $products->get();
Here $request->list is post value which contains 12,13. Mentioned code works fine if I manually type IDs like this.
$products = $products->whereIn('products.id', [12,13]);
But if I try to call same with variable or directly with request post then it is returning only one result.
$products = $products->whereIn('products.id', [$request->list]);
//OR
$id = $request->list;
$products = $products->whereIn('products.id', $id);
Why it is giving only one result when I use variable, any idea?

$request->list contains comma separated values, so convert it to an array. Change it as below:
$products = $products->whereIn('products.id', explode(',',$request->list));
Here is a full query:
$products = product::select('products.*', 'categories.category_name')
->join('categories', 'products.product_category', '=', 'categories.id')
->whereIn('products.id',explode(',',$request->list))
->get();

Related

laravel does not exist on this collection instance

$orders = Orders::select('orders.id as order_id', 'collection_color.color_name as color', 'collection_color.id as collection_color_id', DB::raw('SUM(order_piece.piece) As piece'))
->join('order_piece', 'order_piece.order_id', '=', 'orders.id')
->join('collection_color_size_barcode', 'collection_color_size_barcode.id', '=', 'order_piece.collection_color_size_barcode_id')
->join('collection_color', 'collection_color.id', '=', 'collection_color_size_barcode.collection_color_id')
->whereIn('orders.id', $request->order_id)
->groupBy('order_piece.order_id')
->orderBY('orders.delivery_date', 'ASC')
->get();
return $orders; => [{"order_id":30,"color":"Kahverengi","collection_color_id":21,"piece":"500"}]
return $ccfc = CollectionColorFabricColor::whereIn('collection_color_id', $orders->collection_color_id)->get();
Property [collection_color_id] does not exist on this collection instance. i am getting error can you help me
The error is most likely due to this in your second code snippet: $orders->collection_color_id. $orders is a collection, so the property doesn't exist in that object. What you actually need is to pluck those values from that collection like so:
return $ccfc = CollectionColorFabricColor::query()
->whereIn('collection_color_id', $orders->pluck('collection_color_id'))
->get();
Because your $orders is collection, you need to get collection_color_id array like this :
$arrayColors = $orders->pluck('collection_color_id')->toArray();
then
return $ccfc = CollectionColorFabricColor::whereIn('collection_color_id', $arrayColors)->get();

Laravel whereHas Returns all records

I have have 3 tables in my projects they are:
products(can have Multiple Variants)
variants (belongsto product)
product_attributes (this have product_id,attribute_id,value_id)
I want to filter variants from a product by value ids thats comes from form request as example (1,2,6)
I have tried like this:
$poruduct_id = $request->product_id;
$value_ids = $request->value_ids;
$searched_variants = Variant::whereHas('product.attributeValues', function ($query) use ($value_ids, $product_id) {
$query->whereIn('value_id', [$value_ids]);
})->where('product_id', $product_id)->get();
dd($searched_variants);
But the problem is the query returns all records from the product. What is the solution to filter exactly the values that the product Variants have?
Thank you.
-UPDATED-
I have tried like this but nothing changed
$searched_variants = Variant::select('product_id')->whereHas('product.attributeValues', function ($query) use ($value_ids, $product_id) {
$query->whereIn('value_id', [$value_ids]);
})->groupBy('product_id')
->havingRaw('COUNT(*) = ?', [count((array) $value_ids)])
->get();
-**FİNALLY SOLUTİON**-
I made it like this : I get the value code that is in for example Large the code is L
get all the codes to controller and executed this query ı hope this helps someone
1.$value_codes=$request->value_codes;
2.$value_codes_array=explode(',',$value_codes);
3.$product_id=$request->product_id;
4.$searchValues = preg_split('/,/', $value_codes_array, -1, PREG_SPLIT_NO_EMPTY);
$searchValues = preg_split('/,/', $value_idss, -1, PREG_SPLIT_NO_EMPTY);
$variants= Variant::where(function ($q) use ($searchValues) {
foreach ($searchValues as $value) {
$q->orWhere('sku', 'like', "%-{$value}")
->orWhere('sku', 'like', "%-{$value}-%")
->orWhere('sku', 'like', "{$value}-%");
}
})->where('product_id',$product_id)->get();
dd($variants);
If you have n variants to one product, you query should be like:
Product Model
public function variants: HasMany relationships
//usage
$produtc->variants->and here the query function
You need to use it in this way, it should work:
$productId = $request->product_id;
$valueIds = $request->value_ids;
$searchedVariants = Variant::whereHas('product.attributeValues', function ($query) use ($valueIds) {
$query->distinct()->whereIn('value_id', $valueIds);
}, '=', count($valueIds))->where('product_id', $productId)->get();

How to use where clause with local variable without passing a parameter in Laravel

I joined 2 tables and I want to display document_name from parent table(document_control_reviews) whose ID is currently posted in a child table (initial_approvals). The foreign key that holds the child document is 3.
If I hardcode the query with the ID = 3, I get the correct result just for testing purposes. But I want the documents to be display dynamically using $id instead of 3.
This hardcode test works fine when I use 3 as ID:
public function initial_approval(){
$approval_files = DB::table('document_control_reviews')
->leftJoin('initial_approvals', 'initial_approvals.document_control_review_id', '=', 'document_control_reviews.id')
->leftJoin('files', 'document_control_reviews.file_id', '=', 'files.id')
->select('document_control_reviews.*', 'initial_approvals.*', 'files.*')
->where('initial_approvals.document_control_review_id', '=', 3)
->get();
}
But I need a dynamic ID which is a local variable $id (as showed below):
public function initial_approval(){
$id = 3 //hardcoded. Here is where I'm stuck.
$docId = DocumentControlReview::find($id);
$approval_files = DB::table('document_control_reviews')
->leftJoin('initial_approvals', 'initial_approvals.document_control_review_id', '=', 'document_control_reviews.id')
->leftJoin('files', 'document_control_reviews.file_id', '=', 'files.id')
->select('document_control_reviews.*', 'initial_approvals.*', 'files.*')
->where('initial_approvals.document_control_review_id', '=', $id)
->get();
}
This is what I don't want. I dont need to pass any parameter. I don't need any argument in the method call.
public function initial_approval($id){
$approval_files = DB::table('document_control_reviews')
->leftJoin('initial_approvals', 'initial_approvals.document_control_review_id', '=', 'document_control_reviews.id')
->leftJoin('files', 'document_control_reviews.file_id', '=', 'files.id')
->select('document_control_reviews.*', 'initial_approvals.*', 'files.*')
->where('initial_approvals.document_control_review_id', '=', $id)
->get();
}
This piece of code won't work the way you intend to because here id is a collection not an integer.
$id = DB::table('document_control_reviews')->select('id')->get();
You think id will be an integer like $id = 3 but in fact here $id = Collection({"id"=>3},...) get() always return a collection.
What you are trying to do is unclear please elaborate with an example.
I finally figured it out. I simply use the where clause in my query where the child ID is a positive integer. And I get exactly what I wanted in this code below:
$approval_files = DB::table('document_control_reviews')
->leftJoin('initial_approvals', 'initial_approvals.document_control_review_id', '=', 'document_control_reviews.id')
->select('initial_approvals.*', 'document_control_reviews.*')
->where('initial_approvals.id', '>', 0)
->get();

how to group by item many to many query builder laravel

I have comics and categories related many to many through pivot tables. I use join and groupBy caterories.id but it doesn't group categories same comics id.
If I do not use the group
$result = DB::table('comics')
->select('comics.name','categories.title')
->join('category_comic', 'comics.id', '=', 'category_comic.comic_id')
->join('categories', 'category_comic.category_id', '=', 'categories.id')
->get();
I want each comic group category
(source: uphinh.org)
First of all
try tou use Laravel Eloquent Relationship and its really cool and very easy to use
In Eloquent Method
In Comics Model
add relationship function
public function cat(){
return $this->hasOne(ComicCategory::class,'id','comic_id'); //ComicCategory::class is your category_comic model
}
Then you just need you Comic Model to get a group of your category com
$result = Comic::with('cat')->get(); //Commic is your model
In query Builder, you need to group manual using foreach
$result = DB::table('comics')
->select('comics.name','categories.title')
->join('category_comic', 'comics.id', '=', 'category_comic.comic_id')
->join('categories', 'category_comic.category_id', '=', 'categories.id')
->get();
$result = json_decode(json_encode($result), TRUE);
$new_result = [];
foreach($result as $row){
$arr[$row['id']]['name'] = $row['name'];
$arr[$row['id']]['cat'][] = $row['title'];
}
and finally rearange the key
$new_result = array_values($new_result );
PS : thats array method, i never group using object method

Laravel eloquent and relationship

I have a code:
$response = $this->posts
->where('author_id', '=', 1)
->with(array('postComments' => function($query) {
$query->where('comment_type', '=', 1);
}))
->orderBy('created_at', 'DESC')
->limit($itemno)
->get();
And when I logged this query with:
$queries = \DB::getQueryLog();
$last_query = end($queries);
\Log::info($last_query);
In log file I see follow:
"select * from `post_comments` where `post_comments`.`post_id` in (?, ?, ?, ?) and `comment_type` <> ?"
Why is the question mark for comment_type in the query?
Update #1:
I replaced current code with following and I get what I want. But I'm not sure it is OK. Maybe exists many better, nicer solution.
$response = $this->posts
->where('author_id', '=', 1)
->join('post_comments', 'post_comments.post_id', '=', 'posts.id')
->where('comment_type', '=', 1)
->orderBy('created_at', 'DESC')
->limit($itemno)
->get();
Behind the scene the PDO is being used and it's the way that PDO does as a prepared query, for example check this:
$title = 'Laravel%';
$author = 'John%';
$sql = "SELECT * FROM books WHERE title like ? AND author like ? ";
$q = $conn->prepare($sql);
$q->execute(array($title,$author));
In the run time during the execution of the query by execute() the ? marks will be replaced with value passed execute(array(...)). Laravel/Eloquent uses PDO and it's normal behavior in PDO (PHP Data Objects). There is another way that used in PDO, which is named parameter/placeholder like :totle is used instead of ?. Read more about it in the given link, it's another topic. Also check this answer.
Update: On the run time the ? marks will be replaced with value you supplied, so ? will be replaced with 1. Also this query is the relational query, the second part after the first query has done loading the ids from the posts table. To see all the query logs, try this instead:
$queries = \DB::getQueryLog();
dd($queries);
You may check the last two queries to debug the queries for the following call:
$response = $this->posts
->where('author_id', '=', 1)
->with(array('postComments' => function($query) {
$query->where('comment_type', '=', 1);
}))
->orderBy('created_at', 'DESC')
->limit($itemno)
->get();
Update after clarification:
You may use something like this if you have setup relation in your Posts model:
// $this->posts->with(...) is similar to Posts::with(...)
// if you are calling it directly without repository class
$this->posts->with(array('comments' =. function($q) {
$q->where('comment_type', 1);
}))
->orderBy('created_at', 'DESC')->limit($itemno)->get();
To make it working you need to declare the relationship in your Posts (Try to use singular name Post if possible) model:
public function comments()
{
return $this->hasmany('Comment');
}
Your Comment model should be like this:
class Comment extends Eloquent {
protected $table = 'post_comments';
}

Resources