How to get relation with a alias Model - php

Hello i have a model named Product and 2 model named ProductImage and ProductAttribute
What i wish ?
I want to access to the product attribute and get they element with this:
Product:with(['attribute','image','category']);
If i will access to the attribute laravel return me this error
Syntax error or access violation: 1066 Not unique table/alias: 'product_attributes'
in my Product Model
class Product extends Model
{
protected $fillable = [
'name',
'description',
'category_id',
];
protected $guarded = [
'id',
];
protected $dates = [
'created_at',
'updated_at',
];
public function category()
{
return $this->belongsTo(Category::class);
}
public function attribute()
{
return $this->belongsToMany(ProductAttributes::class,'product_attributes');
}
}
In my ProductAttribute Model
class ProductAttributes extends Model
{
protected $fillable = [
'attribute',
'value',
'price',
'product_id',
'stock'
];
public function product()
{
return $this->belongsTo(Product::class);
}
}
Comment: I'm using laravel as REST API

Related

Can't get variable from Laravel ORM relations

I want to get "$invoice->form->form" parameter here because i want to use it in view. When i am using dd($invoice->form); than gets null. Invoice and form are other tables and models but are connected with laravel relationship and foreign keys in migrations.
public function show(Invoice $invoice)
{
dd($invoice->form);
return view('invoices.show',compact('invoice'));
}
This is begining of invoice controller file:
namespace App\Http\Controllers;
use Kyslik\ColumnSortable\Sortable;
use App\Invoice;
use Illuminate\Http\Request;
use App\User;
use App\Proform;
use App\Form;
use App\Currency;
use DB;
Here is invoice model
<?php
namespace App;
use Kyslik\ColumnSortable\Sortable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Invoice extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
use SoftDeletes;
use Sortable;
protected $table = 'invoices';
protected $fillable = [
'invoicenumber', 'invoicedate', 'id', 'selldate', 'user_id', 'paymentmethod',
'paymentdate', 'status', 'comments', 'city', 'paid', 'autonumber', 'automonth', 'autoyear', 'name',
'PKWIU', 'quantity', 'unit', 'netunit', 'nettotal',
'VATrate', 'grossunit', 'grosstotal', 'form_id', 'currency_id',
];
public $sortable = [ 'invoicenumber', 'invoicedate', 'id', 'selldate', 'user_id', 'paymentmethod',
'paymentdate', 'status', 'comments', 'city', 'paid', 'autonumber', 'automonth', 'autoyear', 'name',
'PKWIU', 'quantity', 'unit', 'netunit', 'nettotal',
'VATrate', 'grossunit', 'grosstotal', 'form_id', 'currency_id',
];
protected $dates = ['deleted_at'];
public $primaryKey = 'id';
public function user()
{
return $this->belongsTo('App\User');
}
public function form()
{
return $this->hasOne('App\Form');
}
public function currency()
{
return $this->hasOne('App\Currency');
}
public function proform()
{
return $this->belongsTo('App\Proform');
}
}
Here is form model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Form extends Model
{
//
protected $fillable = [
'id', 'form',
];
public function invoice()
{
return $this->belongsTo('App\Invoice');
}
public function proform()
{
return $this->belongsTo('App\Proform');
}
}
Because you aren't loading the relation.
On your controller you should query like: $invoice = Invoice::with('form')->find($invoice_id); and return it to the view like: return view('invoices.show', [ 'invoice' => $invoice->form ]);

Eloquent relationships in laravel Problems

I'm having issues with how to deal with tables relationships in laravel. i have three tables Orders table, Order_product table and User table. A User can either be described as a seller or a buyer depending on if they listed or bought something. Now when a user submit order form i get an error
"General error: 1364 Field 'seller_id' doesn't have a default value (SQL: insert into order_product (order_id, product_id, quantity, `up ▶"
Here is how those tables look like in phpmyAdmin
https://imgur.com/a/fvxo1YZ
And below are the models
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'Seller'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
//public function isSeller() {
// return $this->seller;
//}
public function products()
{
return $this->hasMany(Products_model::class);
}
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function orders()
{
return $this->hasManyThrough(Order::class, Products_model::class, 'buyer_id', 'seller_id', 'product_id');
}
public function orderFromBuyers()
{
return $this->hasManyThrough(OrderProduct::class, Products_model::class, 'buyer_id', 'product_id');
}
public function orderFromSellers()
{
return $this->hasManyThrough(OrderProduct::class, Products_model::class, 'seller_id', 'product_id');
}
}
Products_model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class products_model extends Model
{
protected $table='products';
protected $primaryKey='id';
protected $fillable= ['seller_id','pro_name','pro_price','pro_info','image','stock','category_id'];
}
OrderProduct.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class OrderProduct extends Model
{
protected $table = 'order_product';
protected $fillable = ['order_id', 'buyer_id', 'seller_id','product_id', 'quantity'];
public function products()
{
return $this->belongsTo('App\Products_model');
}
public function buyer()
{
return $this->belongsTo(User::class, 'id', 'buyer_id');
}
public function seller()
{
return $this->belongsTo(User::class, 'id', 'seller_id');
}
public function order()
{
return $this->belongsTo(Order::class);
}
}
Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
//protected $table = 'orders';
protected $fillable = [
'shipping_email', 'shipping_name', 'shipping_city', 'shipping_phone', 'billing_subtotal', 'billing_total',
];
public function user()
{
return $this->belongsTo('App\User');
}
public function products()
{
return $this->belongsToMany('App\Products_model')->withPivot('quantity');
}
public function orders(){
return $this->hasMany('App\OrderProduct', 'order_id');
}
}
Here is my store Function
public function store(Request $request)
{
//Insert into orders table
$order = Order::create([
'buyer_id' => auth()->user() ? auth()->user()->id : null,
'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
//Insert into order product table
if ($order) {
foreach(session('cart') as $productId =>$item) {
if (empty($item)) {
continue;
}
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $productId,
// $products=DB::table('products')->where('id',$id)->get();
'quantity' => $item['quantity'],
//dd($item)
]);
}
}
//Empty Cart After order created
$cart = session()->remove('cart');
return redirect()->route('confirmation.index')->with('success_message', 'Thank you! Your payment has been successfully accepted!');
}
the error is very specific:
General error: 1364 Field 'seller_id' doesn't have a default value
(SQL: insert into order_product
And looking at the code you posted, assume it happens here:
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $productId,
'quantity' => $item['quantity'],
]);
You can not create an OrderProduct without giving a value to seller_id when that field doesn't have a default value or is not nullable in DB. So, give it a value when creating the record. Looking at the models, I think you could do something like this:
$product = products_model::find($productId);
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $productId,
'quantity' => $item['quantity'],
'seller_id' => $product->seller_id,
'buyer_id' => $order->buyer_id,
]);
You need to send value of the seller id.
$order = Order::create([
'buyer_id' => auth()->user() ? auth()->user()->id : null,
'seller_id' => $request->seller_id,
'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
or you can remove the seller_id on your Order Table because you can get the seller information from the Product Model
Post model to relationship one to one,
and User model to relationship one to many.

Return many object in my json response using resource

I'm kinda new to Laravel and I hope someone we'll be able to give me some help.
I apologize for my english
So I'm trying to develop an application with some friends to manage our food by sending alert when the peremption date is near.
I'm developing the API, the actual structure is this way:
A user,
A product,
A basket containing the user_id, the product_id and of course the peremption date.
So now when I make a call to get the User 'stock' on my API I wish I could get something like this:
{
'id' : 1,
'peremption_date': XX-XX-XX,
'product' : {
'id' : 3,
'name': bblablabala,
'brand' : blablabala
},
'id' : 2,
'peremption_date': XX-XX-XX,
'product' : {
'id' : 4,
'name': bblablabala,
'brand' : blablabala
},
}
So I took a look on resources and saw that if I define the right relations, this could do the stuff for my output.
I'll link you my actual class declarations and their resources:
User:
//user.php
class User extends Authenticatable
{
use Notifiable, HasApiTokens;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function baskets()
{
return $this->hasMany(Basket::class);
}
}
Product:
//Product.php
class Product extends Model
{
protected $table = 'products';
protected $fillable = ['code_barre', 'product_name', 'generic_name', 'brand', 'quantity'];
public function basket()
{
return $this->belongsToMany(Basket::class);
}
}
//productResource.php
class ProductResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'code_barre' => $this->code_barre,
'product_name' => $this->product_name,
'generic_name' => $this->generic_name,
'brand' => $this->brand,
'quantity' => $this->quantity,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
];
}
}
Basket:
//Basket.php
class Basket extends Model
{
protected $table = 'baskets';
protected $fillable = ['user_id', 'product_id', 'dlc_date'];
public function user()
{
return $this->belongsTo(User::class);
}
public function product()
{
return $this->hasOne(Product::class);
}
}
//BasketResource.php
class BasketResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'dlc_date' => (string) $this->dlc_date,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
'product' => $this->product
];
}
}
So when I try to store a new basket in my store method:
//BasketController.php
public function store(Request $request)
{
$this->product->storeProduct($request->input('code_barre'));
$att = DB::table('products')
->where('code_barre', '=', $request->input('code_barre'))
->first();
$basket = Basket::create([
'user_id' => $request->user()->id,
'product_id' => $att->id,
'dlc_date' => $request->input('dlc_date')
]);
return new BasketResource($basket);
}
I get the following error (this one)
saying than products.id_basket does not exist and its right, it's not supposed to exist. This is Basket who have a product_id. so I know this is coming from the relationship I declared but I can't figure how to do it right.
Can someone come and save me ???
Thanks a lot, I hope you understood me !
Wish you a good day
As I look at your Basket model, it seems you have to change your:
public function product()
{
return $this->hasOne(Product::class);
}
to:
public function product()
{
return $this->belongsTo(Product::class);
}
Because you have product_id in your baskets table. To use hasOne() relation, you will need to remove product_id from baskets table and add basket_id to products table, because hasOne() relation is something like hasMany(), only calling ->first() instead of ->get()

Laravel - Model BelongsTo multiple models

I am developing a system and I have a question, in the system I have 3 main models (User, State, City), to manage the users I use a package for Laravel called Entrust, with this package I can define system roles, one of these roles is the manager, the manager can have Cities and States, however, a States can have several Cities, so in my model Cities BelongsTo to a User and a States.
Is that correct? A model can BelongsTo more then one model? I found no satisfactory answer on Google.
User.php
class User extends Authenticatable
{
use Notifiable;
use EntrustUserTrait;
use SearchableTrait;
protected $fillable = [
'role',
'active',
'status',
'name',
'slug',
'email',
'password',
'cpf',
'rg',
'mothers_name',
'marital_status',
'curriculum',
'psychiatric_report',
'contract',
'phone',
'adress',
'city',
'state',
'country',
];
protected $hidden = [
'password', 'remember_token',
];
protected $searchable = [
'columns' => [
'users.name' => 10,
'users.slug' => 8,
'users.email' => 8,
]
];
public function getRouteKeyName()
{
return 'slug';
}
public function states()
{
return $this->hasMany('App\State');
}
public function cities()
{
return $this->hasMany('App\City');
}
}
State.php
class State extends Model
{
protected $fillable = [
'name',
'slug',
'initials',
'manager_id'
];
public function getRouteKeyName()
{
return 'slug';
}
public function manager(){
return $this->belongsTo('App\User');
}
public function cities(){
return $this->hasMany('App\City');
}
}
City.php
class City extends Model
{
protected $fillable = [
'name',
'slug',
'state_id',
'manager_id',
];
public function getRouteKeyName()
{
return 'slug';
}
public function manager(){
return $this->belongsTo('App\User');
}
public function state(){
return $this->belongsTo('App\State');
}
}

Laravel array instead of collection

In my Laravel application, I have this model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Division extends Model
{
protected $fillable = [
'name','company_id', 'location_id'
];
protected $casts = [
'name' => 'string',
'company_id' => 'integer',
'location_id' => 'integer'
];
public function company()
{
return $this->belongsTo(Company::class);
}
public function location()
{
return $this->belongsTo(Location::class);
}
}
$division->company returns a collection
$division->location returns an array
Why this two relations has different results? (Sorry for bad formating....)
As you've just shown in the comments (and then edited), you're using it with get(). That's why you're getting a collection and not an object.
$division->company returns an object. Then you're running another query with $division->company->anotherRelationship()->get() which returns a collection of related objects.

Categories