I'm having a little problem with laravel that may be easily solved. To be short, the situation is: I have two tables, one for the users and the other one for products that has a column 'user_id' so I can identify the associated user.
In Laravel, I can use
$user = Sentry::getUser(); //Or Auth::user() if you're not using Sentry
$products = DB::table('table2')->where('user_id',$user->id);
And that should give me every product that user has. Good.
Now I want to show the products individually on screen, but unfortunately that doesn't work. It seems I can't echo this information in a string because it's made of multiple rows. I get
Object of class Illuminate\Database\Query\Builder could not be converted to string
For the solution, since the maximum associated products I allowed in the system is 3, I came up with the idea of getting each row separately and echoing them. For the first one, it's simple: $products->first(); but I have no idea on how to get the other two.
And maybe I'm being a newbie here, but I don't think I can use the products' id info since $products->id returns an error.
Can anyone help me?
Thanks in advance!
You want to use take, limit the number of results to three and then print out every one with a foreach loop. Docs: Laravel Queries, see skip and take.
$products = DB::table('table2')->where('user_id',$user->id)->take(3)->get()
Then, inside your view, you can just iterate through this data:
#foreach($products as $p)
Alternatively, in your PHP you can iterate through this data using something like:
foreach ($products as $product) { var_dump($product); }
(You are getting that error because you are trying to output a result object as a whole, and not the data it contains. Using the loop actually fetches the data from the result object so you can then use the loop variable ($product) normally.)
To get data from database you can use one one those methods: all, get, or first.
Using all:
$products = DB::table('table2')->all();
you are getting all the products.
Using first you can use conditions but you will get only first record that fulfil conditions:
$products = DB::table('table2')->where('user_id',$user->id)->first();
Using get you can use conditions and you will get all the records that fulfil those conditions:
$products = DB::table('table2')->where('user_id',$user->id)->get();
So in your case you want to use get to get data from database.
When you are using
$products = DB::table('table2')->where('user_id',$user->id);
Then $products is an array and you do not have to echo an array.
To display the products you need to use a foreach loop like below
foreach ( $products as $key => $product ) {
var_dump( $product );
}
If you want to show only three products, then you can use for loop inside foreach.
You can learn more about foreach from below link
http://php.net/manual/en/control-structures.foreach.php
Related
I have a function in controller which fetches all products based on Auth::id:
$products = DB::table('products')
->where('created_by_id', Auth::id())
->get();
Then has a for each loop as follows which inserts and update:
foreach($products as $key => $product){
$previous_product = Product::create((array) $product);
$previous_product->save();
$previous_product->update(['created_by_id' => $reseller_id->reseller_id]);
}
Which work perfectly, but the problem I am facing is products are duplicated twice instead of duplicated once. as shown on below image:
What I have tried to do is to use replicate() method instead of create() but I got null on replicate and the problem still persists.
Any help given to resolve my issue will be greatly appreciated.
Try to use insertOrIgnore method with query builder It will fix your issue.
DB::table('products')->insertOrIgnore($arrayOfProducts);
I would give replicate another shot:
$products = Product::where('created_by_id', Auth::id())->get();
foreach ($products as $product) {
$product->replicate()
->fill(['created_by_id' => $reseller_id->reseller_id])
->save();
}
The code you have doesn't appear that it would cause 2 new records to be inserted, though the save call you have is unneeded since create creates the record (saves it) and update calls save.
You can also updateOrCreate() method for the operation so that way you're sure to be only updating if the record exists or create. Here's a link https://laravel-news.com/firstornew-firstorcreate-firstor-updateorcreate
hey everyone I'm trying to make my laravel app faster and what I see in debug bar is so many duplicated queries
and why this happens? because I'm calculating discount in the product model and when I'm getting products in my foreach I use $product->discount() and let's see what's happening in the Product model and discount function, there it is
public function discount(){
$seller = ProductSeller::orderBy('price','asc')-where('product_id',$this->id)->first();
$sellerDiscount = Discount::where('seller_id',$seller->seller_id)-latest('created_at')->first();
$brandDiscount = Discount::where('brand_id',$this->brand_id)-latest('created_at')->first();
$categoryDiscount = Discount::whereIn('category_id',$cateName)-latest('created_at')->first();
}
these are the queries that are duplicating in my category pages in a foreach any idea to prevent the duplicating of each query?
Yes it happens, because you are calling function($product->discount()) instead of getting data from that. Try to use eager load to fix this.
And then get data like this,
$product->seller
You can do this from Your main query and put condition in that.
Products table structure
My API should return values (not ids) and that is what i need. In PHP i just did queries to search tables for values, i guess in laravel way for that is close but i am new in this framework and need little help ;]
I was searching and construct something like this :
$products = Products::all();
foreach ($products as $key => $product) {
$product->id_Model = DB::table('models')->select('model')->where('id', '=', $product->id_Model)->get();
}
"models" table contains names
"products" table contains ids of "models" -> products.id_Models = models.id
I i said above my API result should be names instead of ids so i need to search for name of every product before i put it into json.
Ok i get to point i wanted to be result of work
API :
https://prnt.sc/i8cy9w
DB :
https://prnt.sc/i8cytv
Values ale "fake" ones from Seeders, now i only need to fix doubles
/edit
Fixed now it works well :
https://prnt.sc/i8d4u5
example line: $product->id_Colors = DB::table('colors')->select('color')->where('id', '=', $product->id_Colors)->value('color');
I have an Eloquent query in a foreach loop.
My League model is correct, when I echo values, I get correct $match->league_id inside the loop.
I have relative records in my database with that $match->league_id.
foreach ($matchesRaw as $k=>$match) {
$lg= League::find($match->league_id)->first();
echo $lg->name;
}
My problem is my code displays only the first row ($lg->name) in the database. It means my query all the times gets the first row. No matter what is $match->league_id comes in the loop. How can I solve this?
Your problem is that you're calling first like this:
League::first();
So yes, it gets always the first row in that table.
This is because you do just the same as:
$leagueModel = League::find($someId); // returns model
$leagueModel->first() == League::first(); // returns the same model
Instead you simply call League::find($someId), no first at all.
I think you should use join in instead of calling another eloquent object in a loop ..You understand
I'm wondering if Yii has an efficient method for grouping items by type.
Let's say I have the following model:
Tag
------
id
name
type_id
And let's say there are 5 different types of Tags. I want to be able to display in my index all tags in sections by type_id. Is there a Yii-way of accomplishing this?
Outside a framework I would write a function such that results fetched from the DB were stored like this:
$tags[$typeID][] = $tag;
Then in each section I could do something like:
foreach( $tags[$typeID] as $tag )
{
// Here are all tags for one $typeID
}
But I'm having difficulty figuring out how to do this in Yii without:
A) looping through the entire result set first and rewriting it or,
B) running 5 different queries.
When using ActiveRecord simply specify the "index" in the DBCriteria. So in a query do:
ActiveRecordClass::model()->findAll(array('index'=>'type_id'));
That will return an assoc array that your after. TBF it probably executes exactly the same code, but this is obviously easier to use that performing it everywhere.
Assuming that your active record class is called MyActiveRecordClass, the simplest approach should be sufficient:
$models = MyActiveRecordClass::model()->findAll();
$groupedModels = array();
foreach ($models as $model) {
$groupedModels[$model->typeID][] = $model;
}
If you give more specific information about how you intend to display the grouped results it might be that a better approach can be worked out.