Laravel How To Update Nested createMany - laravel

Been having a hard time on figuring out how to implement updating records on a nested createMany based on the store method. I have these models and relations:
User Model:
class User extends Model
{
public function orders() {
return $this->hasMany(Order::class);
}
}
Order Model:
class Order extends Model
{
public function user() {
return $this->belongsTo(User::class);
}
public function subOrders() {
return $this->hasMany(SubOrder::class);
}
}
SubOrder Model:
class SubOrder extends Model
{
public function order() {
return $this->belongsTo(Order::class);
}
public function subOrderProducts() {
return $this->hasMany(SubOrderProducts::class);
}
}
SubOrderProducts Model:
class SubOrderProducts extends Model
{
public function subOrder() {
return $this->belongsTo(SubOrder::class);
}
}
Here are the tables:
orders table:
id name
sub_orders table:
id order_id date price
sub_order_products table:
id sub_orders_id product_id
Then on the store method:
public function store(StoreOrderRequest $request) {
$order = auth()->user()->orders()->create($request->validated());
$order_subs = $order->subOrders()->createMany($request->orders);
$order_sub_products = $request->only('subproducts');
foreach ($order_subs as $key => $value) {
$order_sub->subOrderProducts()->createMany($order_sub_products[$key]['products']);
}
}
What I wanted to achieve is to update or create those sub orders and sub order products. If the sub order is already existing, then update, otherwise create a new record with those corresponding sub order products.
Here's what I've tried so far:
public function store(UpdateOrderRequest $request, Order $order) {
$order->update($request->validated());
$order_subs = $order->subOrders()->updateMany($request->orders);
$order_sub_products = $request->only('subproducts');
foreach ($order_subs as $key => $value) {
$order_sub->subOrderProducts()->updateMany($order_sub_products[$key]['products']);
}
}
It's not working as expected since the order subs is only a single record. What's the best way or the right process for updating/creating these records? Thanks.

Related

Laravel Eloquent HasManyThrough through 3 tables with pivot tables

I need to make a list of scopes from my positions->areas->scopes on my Booking Model.
My tables look like that:
Booking
id
...
Position
id
booking_id
...
Area
id
..
Position_areas
id
area_id
position_id
Scope
id
...
Area_Scopes
id
area_id
scope_id
And this are my relations:
class Booking extends Model
{
...
public function positions()
{
return $this->hasMany(BookingPosition::class);
}
public function areas()
{
return $this->hasManyThrough(Area::class, PositionsAreas::class, 'area_id', 'id', 'position_id', 'area_id');
}
...
}
class BookingPosition extends Model
{
...
public function booking()
{
return $this->belongsTo(Booking::class);
}
public function areas()
{
return $this->belongsToMany(Area::class, 'position_areas', 'position_id', 'area_id')
->using(PositionsAreas::class);
}
...
}
class PositionsAreas extends Pivot
{
...
protected $table = 'position_areas';
public function positions(){
return $this->belongsTo(BookingPosition::class);
}
public function areas(){
return $this->belongsTo(Area::class);
}
...
}
class Area extends Model
{
...
public function bookingPositions()
{
return $this->belongsToMany(
BookingPosition::class
)->using(PositionsAreas::class);
}
public function scopes()
{
return $this->belongsToMany(Scope::class, table: 'scope_areas');
}
...
}
class Scope extends Model
{
...
public function areas(){
return $this->belongsToMany(Area::class, table: 'scope_areas');
}
...
}
And I want to have a list of all areas on my booking model, but I don't know how to achieve that.
So that I can do something like that
...
$booking->load('scopes');
[
id
date
...
scopes => [
{...},
{...}
]
]
I tried to create pivot models for position_areas but i cant even get a list of areas on my booking model.
I couldn't figure out how to solve this with a relation like hasManyThrough but as workaround I make all scopes available in my $bookings like that.
$booking = Booking::find($booking->id);
$booking->scopes = $booking->positions
->pluck('areas')
->flatten()
->pluck('scopes')
->flatten()
->pluck('name')
->unique()
->values()
->all();

Laravel Eloquent many to many relationship with translation

I have a problem with a many to many relationship and the translations of the terms.
I have 4 tables:
products
- id, price, whatever
products_lang
- id, product_id, lang, product_name
accessori
- id, active
accessori_lang
- id, accessori_id, lang, accessori_name
I'm trying to assign accessories to products with an intermediate table named:
accessori_products
this is the model for Product:
class Product extends Model {
protected $table = 'products';
public function productsLang () {
return $this->hasMany('App\ProductLng', 'products_id')->where('lang','=',App::getLocale());
}
public function productsLangAll() {
return $this->hasMany('App\ProductLng', 'products_id');
}
public function accessori() {
return $this->belongsToMany('App\Accessori', 'accessori_products');
}
}
this is the model for productLng:
class ProductLng extends Model {
protected $table = 'products_lng';
public function products() {
return $this->belongsTo('App\Product', 'products_id', 'id');
}
}
Then I have the model for Accessori:
class Accessori extends Model {
protected $table = 'accessori';
public function accessoriLang() {
return $this->hasMany('App\AccessoriLng')->where('lang','=',App::getLocale());
}
public function accessoriLangAll() {
return $this->hasMany('App\AccessoriLng');
}
public function accessoriProducts() {
return $this->belongsToMany('App\Products', 'accessori_products', 'accessori_id', 'products_id');
}
}
And the model for AccessoriLng:
class accessoriLng extends Model {
protected $table = 'accessori_lng';
public function accessori() {
return $this->belongsTo('App\Accessori', 'accessori_id', 'id');
}
}
the last model is for the relationship between the two tables above:
class ProductAccessori extends Model {
protected $table = 'accessori_products';
public function accessoriProducts() {
return $this->belongsTo('App\Product', 'accessori_id', 'products_id');
}
}
I'm trying to get the accessories of each product and to get also the translation but I'm having a lot of problem with this.
It's my first time with a many to many relation with translations too.
Can anyone put me on the right direction?
controller
$products = Product::has('accessori')->with([
'productsLang ',
'accessori' => function ($accessori){
$accessori->with([
'accessoriLang'
]);
}
])->get();
return $products;
you'll get products with accessori that has accessoriLang.

Laravel BelongsToMany with two pivot table

I have the following table structure:
products
id
product_formats
id
product_id
product_prices
id
product_format_id
market_id
markets
id
A product can have multiple formats, with each having their own price which belongs in a different market. How can I retrieve the list of Markets from the Product model?
I used to have a single pivot table, however now I have two pivot.
class Product extends Model
{
public function markets()
{
return $this->belongsToMany(Market::class);
}
}
Update
To get the result I want, I did the following:
public function markets()
{
return Market::whereIn('id', $this->prices()->distinct()->pluck('market_id')->toArray());
}
However, I'm wondering if there's a way to accomplish this via a relationship.
You need to build relationships in models.
ProductModel:
public function productFormats()
{
return $this->belongTo(ProductFormatsModel::class);
}
ProductFormatsModel:
public function productPrices()
{
return $this->belongTo(ProductPricesModel::class);
}
ProductPricesModel:
public function markets()
{
return $this->hasOne(MarketsModel::class);
}
in Controller:
foreach($product->productFormats as $productFormat)
{
foreach($productFormat->productPrices as $productPrice)
{
var_dump($productPrice->markets);
}
}
For unique markets
in ProductModel:
public function productPrices()
{
return $this->hasManyThrough(
'App\ProductPricesModel',
'App\ProductFormatsModel',
'product_id',
'product_format_id'
'id',
'id'
);
}
in Controller
foreach($product->productPrices as $productPrice)
{
var_dump($productPrice->markets)
}

Laravel Eloquent hasMany and BelongsToMany not returning using with

I am trying to do a single query to get back an order and the card to charge, but getting an error.
Card model:
class Card extends Eloquent {
protected $guarded = array();
public static $rules = array();
public function user()
{
return $this->belongsTo('User');
}
public function orders()
{
return $this->hasMany('Order');
}
}
Order model:
class Order extends Eloquent {
protected $guarded = array();
public static $rules = array();
public function user()
{
return $this->belongsTo('User');
}
public function card()
{
return $this->hasOne('Card');
}
public function address()
{
return $this->belongsTo('Address');
}
public function orderItems()
{
return $this->hasMany('OrderItem');
}
}
What I am trying to get back:
$order = Order::with('card')->find($id);
This obviously doesn't work and I have tried several combos. I think the issue is with my models/relationships.
Any idea how I can get back the order with the card/token details?
DB info: Each order can have only one card_id and each card can be in many orders. There is no order_id in the card.
Orders table basically:
id | card_id
Cards table:
id | token
Trying to get the token col to return with the Order.
In your Order model, you need to change this:
public function card()
{
return $this->hasOne('Card');
}
to this:
public function card()
{
return $this->belongsTo('Card');
}
The reason is that you are defining the inverse of the hasMany relationship. With the belongsTo relationship, Eloquent will look for a card_id column on the orders table.

Laravel 4 many to many and polymorphic in one direction

I'd like a relationship between a few models that is a many to many and polymorphic in one direction, this is how I've solved it for now but it really bothers me to have it this way, I loose all attach(), detach() etc functionality and it should be a simple way to do this. Can't find any docs, examples or anything, all I've seen are just so basic.
<?php
use Illuminate\Database\Eloquent\Collection;
class Category extends Eloquent {
/*
public function categorizables() {
return $this->morphTo();
}
*/
public function categorizables(){
$categorizables = new Collection();
$categorizableRows = DB::table('categorizables')->where('category_id', $this->id)->get();
foreach ($categorizableRows as $categorizable) {
$class = $categorizable->categorizable_type;
$categorizables->add($class::find($categorizable->categorizable_id));
}
return $categorizables;
}
}
class Article extends Eloquent {
/*
public function categories() {
return $this->morphMany('Category','categorizable');
}
*/
public function categories(){
$categoryRows = DB::table('categorizables')
->where('categorizable_id', $this->id)
->where('categorizable_type', get_class($this))->get();
$categoryIds = array();
foreach ($categoryRows as $category) {
$categoryIds[] = $category->id;
}
return Category::find($categoryIds);
}
}
class Person extends Eloquent {
/*
public function categories() {
return $this->morphMany('Category','categorizable');
}
*/
public function categories(){
$categoryRows = DB::table('categorizables')
->where('categorizable_id', $this->id)
->where('categorizable_type', get_class($this))->get();
$categoryIds = array();
foreach ($categoryRows as $category) {
$categoryIds[] = $category->id;
}
return Category::find($categoryIds);
}
}
/*
Table categorizables
id
category_id
categorizable_type (Possible "Article" or "Person" in this case)
categorizable_id (id of Article or Person)
Table categories
id
name
Table articles
id
name
content
Table People
id
name
content
*/

Resources