I have a persistent problem with all my project and I need help understanding how to make it work.
In my view =
URL = mysite.com/product/40 so here the product ID is 40
On the view I am doing a foreach loop to show all merchants that have this product. we have many merchants having many products so it is a many to many relationship.
Now on my controller
$product = Product::find($id); // to find the product
$users = $product->users; // here the user is the merchant that have the product
$store = Store::where('user_id', $user->id)->value('social');
Here i get the error :
Trying to get property of non-object
So I do want to access the store of each of the merchants in the controller how do I do this ? Because now $user is a collection.
Please first verify if the store is giving object or not by using var_dump. After that you can have a look into https://laravel.com/docs/5.6/queries for more details.
1) Firstly you can use Injection to avoid this line: $product = Product::find($id);
public function your_controller_methon(Product $product) {}
Laravel will automatically do the trick for you and $product will already contain Product object.
2) If you have relationship, you should do something similar to this:
$product->stores - to retrieve all stores which contains particular product in product_id column. And you could do: $product->stores()->pluck('social'); to retrieve list of socials from all merchants which have particular product.
About relationships you could read here: https://laravel.com/docs/5.7/eloquent-relationships
You can refactor your code to use the whereIn() query builder method since you have many users to a product. You will have something like:
$product = Product::find($id); // to find the product
$users = $product->users->pluck('id');
$stores = Store::whereIn('user_id', $users->all())->value('social');
This mean your $stores variable will contain those stores owned by the users.
PS: Be sure to check if $users is not empty or null so you don't encounter unexpected errors
According to you code, Here $user is a single value, not a collection.
Change:
$store = Store::where('user_id', $user->id)->value('social');
To
$store = Store::where('user_id', $user);
It will works.
To make the $user as a collection, execute such query so that it will return array such as:
$product = Product::find($id);
$user = Product::where('user', $product->user)->get();
This will return the collection of users of this product.
Then execute foreach loop:
foreach($user as $rowdata){
$store = Store::where('user_id', $rowdata->id)->get();
}
You should try this:
$product = Product::find($id);
$user = Product::where('user', $product->user)->get();
foreach($user as $rowdata){
$store = Store::where('user_id', $rowdata->id)->get();
}
Related
I have controller with request like below
$product = $request->product; //array
$product_category = $request->product;
if($request->filled('product')){
$product = product()::whereIn('product',$product)
->where('product_category',$product_category)
->get();
}else {
$product = product()::where('product_category',$product_category)
->get();
}
how do i skip or make the eloquent still worked if $product request was not filled or null?
Currently i used the if for that query is remove where on product, but that will make me create alot of eloquent with more request
But I think this is not the best or right think to do, what is my better option for doing that where without writing a lot of if-elseing?
Use when function provided by laravel:
Product::when($request->product, function($query, $product) {
$query->whereIn($product);
})->where("product_category", $product_category)->get();
Question: How can I run the where query for all rows in $cart, instead for just $cart[0], or [1] or [2].
I am trying to manually code a Shopping Cart in Laravel. Since I am a novice, I am stuck at a point. Please take a look at the code below:
public function showCart()
{
$user = Auth::user();
$cart = Cart::where('user_id', $user->id)->get();
$product = Products::where('id', $cart[0]->product_id)->get();
return view('showCart')
->with('cart', $cart)
->with('user', $user)
->with('product', $product);
}
This is my function to show a user's cart. Here, I am trying to show all the products that a user has in his cart, and also send a variable with the product details.
However, while I am trying to send all the products in the user's cart as a $product array, I am only getting the first product. That is because the rows returned in $cart is more than one, but I am unable to write a query for getting all the products in this line:
$product = Products::where('id', $cart[0]->product_id)->get();
. . . because, quite clearly, I am writing a query to match only the first row returned in $cart.
Thanks in Advance.
You can use the whereIn and the data_get helper function:
$product = Products::whereIn('id', data_get($cart, '*.product_id'))->get();
data_get works with both arrays and objects. Alternatively, you can use Arr::get for arrays only.
I'm in a controller for Laravel 5.2 and am trying to iterate through an eloquent collection of invoice_items, which would translate to something like order items. So, the invoice would act as the order, have it's ordered items (invoice_item), and the invoice_items would list all of the products ordered (product).
Here's what I have:
$id = $value; //from param
$invoice = Invoice::where('id', $id)->get();
$invoice_items = Invoice_item::all()->where('invoice_id', $invoice[0]->id);
$contact = Contact::where('id', $invoice[0]->contact_id)->get();
foreach($invoice_items as $item) {
$products = Product::all()->where('id', $item->product_id);
}
I'm attempting to pull all of the products from that specific invoice (via invoice items), which in this specific case should be two, different products.
What's happening, is when I iterate through using that loop, it's adding the same product twice, whereas it should be adding each product once. Is my logic just wrong here? Or do I need to look at my relationships again or something?
Change your queries to:
$invoice = Invoice::where('id', $id)->get();
$invoice_items = Invoice_item::where('invoice_id', $invoice[0]->id)->get();
$contact = Contact::where('id', $invoice[0]->contact_id)->get();
foreach($invoice_items as $item) {
$products = Product::where('id', $item->product_id)->get();
}
An easier way may be to add a items relation to the InvoiceItems model. E.g.:
public function items()
{
$this->hasOne('Items');
}
Then you can get all the Items from Invoice_item using:
return $invoice_items->items;
You can also try:
$invoice = Invoice::where('id', $id)->get();
$invoice_items = Invoice_item::where('invoice_id', $invoice[0]->id)->get()->lists('product_id');
$contact = Contact::where('id', $invoice[0]->contact_id)->get();
$products = Product::whereIn('id', $invoice_items)->get();
Hopefully, $products will then contain a collection of products for that invoice. No need for a foreach loop.
In my site I have users and items. Users can create items. I want to get an array that has all users, where the users which have an item go first and the users which do not have an item go after.
So far I have done this:
$users = User::all();
foreach($users as $user) {
if ($user->item) {
$sortedUsers + $user;
}
// now loop again and add users without relationship
This is pretty inefficient and I'm sure there's a much better way to do it.
You can query on the existence of a relationship
$users = User::has('items')->with('items')->get();
with that syntax you are telling laravel to fetch all users that have a item and to eager load the items;
Edit:
After reading it does not look like you actually want the items just the users that have a item in that case all you need is
$users = User::has('items')->get();
Without seeing the relation of Items to Users I'm not sure if this will work but you can try the following:
$users = Users::select('users.*')->orderBy('items.id')->with('items')->get();
Or it might work with just:
$users = Users::orderBy('items.id')->with('items')->get();
Update
$users = Users::orderBy('items.id')->join('items', 'items.user_id', '=', 'users.id')->get();
you can try
$users = User::with('item')->get();
foreach ($users as $user) {
echo $User->item->name;
}
You can use has() to get users with items and doesntHave() to get users without items:
$withItems = User::has('items')->get();
$withoutItems = User::doesntHave('items')->get();
And then merge() two collections:
$users = $withItems->merge($withoutItems);
You said you want an array, so you can convert result into an array with toArray()
$array = $users->toArray();
Please I am trying to create a module in magento that edits the products' name by concatenating the existing product names with randomly generated numbers.
$model = Mage::getModel('catalog/product') ->load(1111) //getting
product model
$collection = $model->getCollection(); //products collection
foreach ($collection as $product) //loop for getting products
{
$model->load($product->getId());
$pname = $product->getName();
$this->model = Mage::getModel('catalog/product');
$new_name = $pname.' '.rand(1000,5000);
$this->model->setName($new_name);
}
This is my code, I am trying to create a module to achieve this functionality without editing the core files or using the admin panel.
Sorry but your code is ugly.
If you want to use collection (that is a good way to access data from a list of object) you must not use a ->load() (very expensive and should be used only when accessing data for a single object, like a product page)
Try this code instead :
$collection = Mage::getModel('catalog/product')->getCollection(); //products collection
$collection->addAttributeToSelect('name'); //retrieve only product name (optimising SQL)
foreach ($collection as $product) //loop for getting products
{
$pname = $product->getName();
$new_name = $pname.' '.rand(1000,5000);
$product->setName($new_name);
$product->save(); // you missed that
}
If you have a high number or product, you could also make a single SQL query with the SQL CONCAT() function ...
class Digital_GoogleMpn_Model_Observer {
public function googleMpn(Varien_Event_Observer $observer)
{
$product = $observer->getEvent()->getProduct();
$pname = $product->getName();
$google_mpn = rand(1000,5000);
$new_name = "{$pname}.' '.{$google_mpn}";
$product->setName($new_name);
$product->save();
} }