GROUP BY the relationship data in laravel - 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();

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);
}

Laravel API Resource returned Undefined property: stdClass::$book",

I have a pivot table Book_Category which store the relationship between book table and category table.
In my Book model I have this
public function categories()
{
return $this->belongsToMany(Category::class);
}
In my Category Model` I have this
public function books()
{
return $this->belongsToMany(Book::class);
}
I don't think I need a model for Book_Category since its a pivot table.
But now I need to create an API Resource. I am trying to return a Book of a particular Category
So I do this this
public function singlepage(Request $request,$book)
$relatedCategory = BookCatResource::collection(DB::table('book_category')
->where('category_id', $request->category_id)->get());
I am using query builder because I don't have a model
In my resource, I have this
public function toArray($request)
{
return [
'book_id' => new BookResource($this->book),
'category_id' => $this->category_id
];
}
But it returned error
Undefined property: stdClass::$book",
In your scenario, you do not need to use the model for pivot table,
what you can do is that
Route::get('/', function () {
return CategoryResource::collection(Category::where('id', 1)->get());
});
CategoryResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class CategoryResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->title,
'books' => BookResource::collection($this->books),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
BookResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class BookResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}

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]);
}

Laravel fractal transformers - not getting includes

I am using fractal package in laravel 5.3. I have a player model who has hasMany relationship with videos, so one player has many videos.
Player model:
public function videos()
{
return $this->hasMany(Video::class);
}
Video model:
public function player()
{
return $this->belongsTo(Player::class);
}
I am trying to send player data and include videos data with it. This is the code in the controller:
$player = fractal()
->item($player)
->parseIncludes(['videos'])
->transformWith(new PlayerTransformer)
->toArray();
And this is the PlayerTransformer:
<?php
namespace App\Transformer;
use App\Player;
class PlayerTransformer extends \League\Fractal\TransformerAbstract
{
protected $availableIncludes = [
'videos'
];
public function transform(Player $player)
{
return [
'id' => $player->id,
'first_name' => $player->first_name,
'last_name' => $player->last_name,
'image' => $player->image_filename,
'club' => $player->club,
'birthday' => $player->birthday,
];
}
public function includeVideos(Player $player)
{
$videos = $player->videos()->where('processed', 1)->get();
return $this->collection($videos, new VideoTransformer);
}
}
I am getting the player data, but I don't get anything for videos. This doesn't work, but what is even weirder if try that with videos, in whose transformer I don't even have includes function:
<?php
namespace App\Transformer;
use App\Video;
class VideoTransformer extends \League\Fractal\TransformerAbstract
{
public function transform(Video $video)
{
return [
'id' => $video->id,
'uid' => $video->uid,
'title' => $video->title,
'image' => $video->getThumbnail(),
'description' => $video->description,
'views' => $video->viewCount(),
'created_at' => $video->created_at->diffForHumans(),
];
}
}
But, when I try to include the player data there, that works:
$videos = fractal()
->collection($videos)
->parseIncludes(['player'])
->transformWith(new VideoTransformer)
->toArray();
I have tried then to apply the same setup I have for the video transformer and remove the $availableIncludes and includeVideos in the player transfomer, but it again didn't work there. What am I doing wrong?
I was doing a get without authentication to test my controller and it was giving the error:
PHP Fatal error: Type of App\Transformers\CustomerCategoryTransformer::$availableIncludes must be array (as in class League\Fractal\TransformerAbstract) in /app/Transformers/CustomerCategoryTransformer.php on line 8
I commented out the line:
protected $defaultIncludes = [];
protected $availableIncludes = [];
My code:
<?php
namespace App\Transformers;
use App\Models\CustomerCategory;
use League\Fractal\TransformerAbstract;
class CustomerCategoryTransformer extends TransformerAbstract
{
// protected $defaultIncludes = [];
// protected $availableIncludes = [];
public function transform(CustomerCategory $model)
{
return [
'id' => $model->id,
'uuid' => $model->uuid,
'seq' => $model->seq,
'slug' => $model->slug,
'name' => $model->name,
'active' => $model->active,
'created_at' => $model->created_at->toDateTimeString(),
'updated_at' => $model->updated_at->toDateTimeString(),
];
}
}

Error storing Topic Model into the database using Sentinel

I have a small forum, im trying to create topic and replies for the store method.
routes.php
Route::get('board/{id}/create', 'TopicsController#create');
Route::post('board/{id}/create', 'TopicsController#store');
TopicsController.php
public function store()
{
$this->request->user()->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}
I am receiving this error.
Call to a member function topics() on null
Also note, i am using Sentinel https://github.com/rydurham/Sentinel from this repo.
<?php namespace App\Models;
class User extends \Sentinel\Models\User
{
protected $fillable = ['email', 'first_name', 'last_name'];
protected $hidden = ['password'];
public function topics()
{
return $this->hasMany(Topic::class);
}
public function replies()
{
return $this->hasMany(Reply::class);
}
public function getGravatarAttribute()
{
$hash = md5(strtolower(trim($this->attributes['email'])));
return "https://www.gravatar.com/avatar/$hash";
}
}
Updated Model
public function store($id)
{
$user = Sentry::getUser($id);
$user->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}
It seems that your user object is null. Properly retrieve the user using the id
public function store($id)
{
$user = \App\Models\User::find(\Sentinel::getUser()->id);
$user->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}

Resources