Attempt to read property "price" on null in laravel? - laravel

I am trying to make order management system. for that i make 2 tables orders and orderitems for order.
I want to get price of selected product through relationship.
This is my OrderController
public function store(Request $request)
{
$product = Product::all();
$order = Order::create([
'user_id' => $request->input('user_id'),
'total' => 1,
]);
$size = count(collect($request)->get('quantity'));
for ($i = 0; $i < $size; $i++) {
$orderitem = Orderitem::create([
'order_id' => $order->id,
'product_id' => $request->get('product_id')[$i],
'quantity' => $request->get('quantity')[$i],
'price' => $order->$product->price,
'total' => 3,''
]);
}
return redirect()->route('orders.index');
}
and this is my order model.
protected $table = "orders";
protected $fillable = [
'user_id',
'total',
];
public function user() {
return $this->belongsTo(User::class);
}
public function product() {
return $this->belongsTo(Product::class);
}
public function orderitem() {
return $this->hasMany(Orderitem::class);
}
This is my Product model
use HasFactory;
protected $table = "products";
protected $fillable = [
'name',
'price',
];
public function order() {
return $this->hasMany(Order::class);
}
and this is my products table
this is my orders table
this is my orderitems table

You are accessing price wrongly. 'price' => $order->$product->price,It should be
'price' => $order->product->price,
Updated
I think you can modify relationship to belongsToMany
Order Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
use HasFactory;
protected $guarded=['id'];
public function product(){
return $this->belongsToMany(Product::class,'order_items')->withPivot('quantity', 'price','total')->withTimestamps();
}
}
Product Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
protected $guarded=['id'];
}
In your controller method
$order = Order::create([
'user_id' => 1,
'total' => 1,
]);
$order->product()->sync([
1=>['quantity'=>2, 'price'=>20,'total'=>40],
2=>['quantity'=>1, 'price'=>10,'total'=>10],
]);
first you build array like multidimensional array structure like
[
productid=>['quantity'=>value, 'price'=>value,'total'=>value],
productid=>['quantity'=>value, 'price'=>value,'total'=>value],
]
Not sure how your $request data will be i guess you can do the following
$size = count(collect($request)->get('quantity'));
$orderitem=[];
for ($i = 0; $i < $size; $i++) {
$orderitem[$request->get('product_id')[$i]] = [
'quantity' => $request->get('quantity')[$i],
'price' => Product::find($request->get('product_id')[$i])->price,
'total' => 3,
]);
}
then you can pass like
$order = Order::create([
'user_id' => 1,
'total' => 1,
]);
$order->product()->sync($orderitem);
Note:This is just snippet to guide you .You can improve logics better than this

Related

How to make a CRUD for a PackageItem table and get the Item via foreignKey in another table? in Laravel

This is my Item model. I have made a function arrayPackageItemSelect that gets the id and equivalent it to the item name.
class Item extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'name',
'price',
'itemdescription',
'activeInactive'
];
public function packageitems()
{
return $this->hasMany(PackageItem::class);
}
public static function arrayPackageItemSelect()
{
$arr = [];
$items = Item::all();
foreach($items as $item){
$arr[$item->id] = $item->name;
}
return $arr;
}
}
my PackageItem Model
class PackageItem extends Model
{
protected $fillable = [
'user_id',
'item_id',
'price'
];
protected $table='packageitems';
public static function itemModel()
{
return $this->belongsTo(Item::class);
}
}
my PackageItem Controller (CREATE) and getting the Item ID from another table (Foreign key) so I can put a category for it.
public function addPackageItem(Request $request)
{
$user = Auth::user();
$item = Item::arrayPackageItemSelect();
echo $item; // when I echo this I get Array to Conversion String in POSTMAN
$fields = $request->validate([
'user_id' => 'required',
'item_id' => 'required',
'price' => 'required|numeric'
]);
// // echo $items;
$package = PackageItem::create([
'user_id' => $user->id,
'item_id' => $item,
'price'=> $fields['price']
]);
return response($package, 201);
}
What I get when I echo the Items
The results I get from POSTMAN
My Schema
This is where my reference is https://www.artofcse.com/learning/product-view-insert-update-delete
Can anybody help me what is wrong?
In your controller (addPackageItem method):
$package = PackageItem::create([
'user_id' => $user->id,
'item_id' => $fields['item_id'],
'price'=> $fields['price']
]);
Also, i think there is an error in your PackageItem model. belongsTo should not be called in a static method :
public function itemModel()
{
return $this->belongsTo(Item::class);
}

How to seed 2 tables that are related to each other in Laravel 8

So I have 2 tables one is the User table and the other is the related UserProfile table. I wanted to fill them with dummy data but I cant get it to work that when I run the seeder it will fill both tables. For now it will fill the User table with dummy data only.
Solution found(any sugestions are welcome)
User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use App\Models\UserProfile;
class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable, HasApiTokens;
protected $table = 'user';
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
public function profile()
{
return $this->hasOne(UserProfile::class, 'user_id');
}
}
UserProfile.php
namespace App\Models;
use App\Models\User;
class UserProfile
{
protected $table = 'user_profile';
protected $fillable = [
'user_id',
'firstname',
'lastname',
];
public function user()
{
return $this->belongsTo(User::class, 'id');
}
}
UserFactory.php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'name' => $this->faker->firstName,
'email' => $this->faker->unique()->safeEmail,
'active' => mt_rand(0,1),
'role' => mt_rand(0,5),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'remember_token' => Str::random(10),
];
}
}
UserProfileFactory.php
namespace Database\Factories;
use App\Models\UserProfile;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserProfileFactory extends Factory
{
protected $model = UserProfile::class;
public function definition()
{
return [
'user_id' => User::Factory(),
'firstname' => $this->faker->firstName,
'lastname' => $this->faker->lastName,
'default_language' => 'en',
];
}
}
DatabaseSeeder.php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
//solution
User::factory(100)->hasProfile(1, function (array $attributes, User $user) {
return ['firstname' => $user->name];
})->create();
}
}
Could you give this a try:
public function definition()
{
$user = [
'name' => $this->faker->firstName,
'email' => $this->faker->unique()->safeEmail,
'active' => mt_rand(0, 1),
'role' => mt_rand(0, 5),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'remember_token' => Str::random(10),
];
UserProfile::create([
'user_id' => $user->id
//any other extra data you have in the user_profiles table
]);
return $user;
}
You need to use for method, Belongs To Relationships
UserProfile::factory()
->for(User::factory()->state([
'name' => 'name', // optional
...
]), 'profile')->state([
'firstname' => 'firstname', // optional
...
])->create();
or
$users = User::factory()->count(100)->create();
foreach ($users as $key => $user) {
UserProfile::factory()
->for($user, 'profile')
->create();
}

GROUP BY the relationship data in laravel

I am fetching products along with its relationship. I have done this:
$data = $this->products->with('images')->with('colors')->where('slug', $slug)->first();
And in the Product model, I have written:
public function images(){
return $this->hasMany('App\Models\ProductImages', 'product_id');
}
public function colors(){
return $this->hasMany('App\Models\ProductSizes', 'color_id');
}
I am storing color_id in the product_sizes table so now when I do dd($data). It gives me 5 data inside the object where the size_id are different but the color_id are same. Is it possible to group the data coming in colors relationship?
I tried using array_unique in the blade but that did not gave me to use the following function:
public function colorInfo(){
return $this->belongsTo('App\Models\Color', 'color_id');
}
I want to group the color_id coming in the colors relationship to display available colors of the product.
Code as per request:
Product Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = ['name','slug','sku','category_id','brand_id','video','status', 'specification', 'description','warranty', 'vendor_id'];
public function getRules(){
$rules = [
'name' => 'bail|required|string|unique:products,name',
'slug' => 'bail|required|string|unique:products,slug',
'sku' => 'bail|required|string|unique:products,sku',
'specification' => 'bail|required|string',
'description' => 'bail|required|string',
'category_id' => 'required|exists:product_categories,id',
'brand_id' => 'nullable|exists:brands,id',
'vendor_id' => 'nullable|exists:vendors,id',
'video' => 'nullable|string',
'warranty' => 'nullable|string',
'status' => 'nullable|in:active,inactive',
];
if($rules != 'add'){
$rules['name'] = "required|string";
$rules['slug'] = "required|string";
$rules['sku'] = "required|string";
}
return $rules;
}
public function category(){
return $this->belongsTo('App\Models\ProductCategory');
}
public function brand(){
return $this->belongsTo('App\Models\Brand');
}
public function VendorName(){
return $this->belongsTo('App\Models\Vendor', 'vendor_id');
}
public function images(){
return $this->hasMany('App\Models\ProductImages', 'product_id');
}
public function sizes(){
return $this->hasMany('App\Models\ProductSize', 'product_id');
}
public function colors(){
return $this->hasMany('App\Models\ProductSize', 'product_id');
}
public function finalCategory(){
return $this->belongsTo('App\Models\SecondaryCategory', 'category_id');
}
}
PRoduct Sizes Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ProductSize extends Model
{
protected $fillable = ['product_id','size_id', 'selling_price', 'purchase_price', 'discount','stock', 'color_id', 'quantity','total_price'];
public function getRules(){
$rules = [
'product_id' => 'required|exists:products,id',
'size_id' => 'required|exists:sizes,id',
'color_id' => 'required|exists:colors,id',
'selling_price' => 'required|string',
'purchase_price' => 'required|string',
'quantity' => 'required|string',
'total_price' => 'required|string',
'discount' => 'nullable|string',
'stock' => 'required|string',
];
return $rules;
}
public function colorInfo(){
return $this->belongsTo('App\Models\Color', 'color_id');
}
}
Get the product first.
$data = $this->products->with(['images', 'colors'])->where('slug', $slug)->first();
To get the distinct colors for that product.
$unique_product_colors = $data->colors->unique('color_id');
unique('color_id') method can be applied on a collection instance to get a new collection in which all the items will have unique color_id
Try This
$data = $this->products->with('images')->with('colors')->where('slug', $slug)->groupBy('product_sizes.color_id')->first();

Model not displaying data, but saving data, Laravel

I have an Image model it saves data through the controller but it doesn't display data, please what's the issue.
The Model
namespace App;
use App\Event\NotifyPhoto;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
public $table = "images";
protected $guarded = [];
public $timestamps = false;
public function property_user()
{
return $this->belongsTo('App\PropertyUser');
}
public function facility(){
return $this->belongsTo('App\Facility');
}
}
The Image controller
namespace App\Http\Controllers;
use App\Http\Requests\ImageRequest;
use App\Property;
use App\PropertyUser;
use Illuminate\Http\Request;
use App\Facility;
use App\Image;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Carbon;
class ImageController extends Controller
{
public function create()
{
dd(Image::all());//This comes back empty
return view('settings.photos');
}
public function store(Request $request)
{
$property_users = PropertyUser::where('user_id', '=', Auth::user()- >id)->get();
foreach ($property_users as $property_user) {
$id = $property_user->property_id;
}
$rules = [
'file' => 'required',
'description' => 'required',
'tag' => 'required'
];
$request->file('file');
if (!empty($request->file('file'))) {
$file_count = count($request->file('file'));
} else $file_count = null;
foreach (range(0, $file_count) as $index) {
$rules['file.' . $index] = 'image|mimes:jpeg,gif,webp,bmp,png|max:2048';
}
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return back()
->withErrors($validator)
->withInput();
} else {
$files = $request->file('file');
$description = $request->input('description');
$tag = $request->input('tag');
$i = 0;
foreach ($files as $file) {
$i++;
$file1 = $file->move(public_path() . '/upload_images/', $file->getClientOriginalName());
$url1 = $url = URL::to("/") . '/upload_images/' . $file->getClientOriginalName();
$image = Image::create([
'filename' => $url,
'description' => $description,
'facility_id' => 16, //$new_fac->id ?? $f->id,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
'tag' => $tag
]);
dd($image);//This displays the files saved and their ids in the table
]
}
return redirect('settings/photos');
}
}
}
Try adding this to your App/Image:
protected $fillable = [
'filename',
'description',
'facility_id',
'created_at',
'updated_at',
'tag',
];
https://laravel.com/docs/5.6/eloquent#mass-assignment
Also, can you confirm a new row is being added to the database?

Laravel update pivot table

In laravel I'm trying to update a row from a pivot table. I have this relationships:
Invoice.php
class Invoice extends Model
{
public function items() {
return $this->belongsToMany('App\Item', 'invoice_items', 'invoice_id', 'item_id')->withPivot('quantity');
}
Item.php
class Item extends Model
{
public function invoices() {
return $this->belongsToMany('App\Invoice' ,'invoice_items', 'item_id', 'invoice_id')->orderBy('created_at', 'desc')->withPivot('quantity');
}
}
InvoiceItem.php
class InvoiceItem extends Pivot
{
protected $fillable = [
'quantity',
];
public function __construct(Model $parent, array $attributes,
$table, $exists = false)
{
parent::__construct($parent, $attributes, $table, $exists);
}
}
and in InvoicesController.php I have method update:
public function update(Request $request, $id)
{
$invoice = Invoice::findOrFail($id);
$invoice->update([
'number' => $request->number,
'status' => $request->status,
'place_issue' => $request->place_issue,
'date_issue' => $request->date_issue,
'date_payment' => $request->date_payment,
'description' => $request->description,
'company_id' => $request->company_id,
'user_id' => $request->user_id,
]);
Invoice::find($id)->items()->updateExistingPivot($request->quantity, ['quantity' => $request->quantity]);
return redirect('listInvoice');
}
Every time I try to update the field "quantity" is the old value. What am I doing wrong?
As each invoice may have multiple items, you can loop through and update the quantity of the item by its key.
I'm not sure what $request->quantity is returning. You may need some additional logic to ensure you are updating the correct item.
$items = $invoice->items->pluck('name', 'id')->toArray();
foreach ($items as $key => $item) {
$invoice->items()->updateExistingPivot($key, ['quantity' => $request->quantity]);
}

Resources