Laravel Updating Relationship Column in WhereHas - php

I wanted to update a column in my model with a wherehas. However, I'm not sure how to do this. Here's my query below
$unused = Sale::whereHas('salesdetails',function($query) {
$query->where('product_id', '<=', 24)->where('switch', 1);
})->where(DB::raw("(DATE_FORMAT(transaction_date,'%Y-%m-%d'))"), '<', $now)->update(['switch' => 0]);
Sale Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sale extends Model
{
protected $table = 'sales';
protected $primaryKey = 'id';
public $timestamps = false;
public function user()
{
return $this->belongsTo('App\User', 'member_id', 'id');
}
public function guest()
{
return $this->belongsTo('App\Guest', 'guest_id', 'id');
}
public function salesdetails()
{
return $this->hasOne('App\Sales_details','sales_id', 'id');
}
public function discount()
{
return $this->hasOne('App\Discount','id', 'discount_id');
}
}
Salesdetails Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sales_details extends Model
{
protected $table = 'sales_details';
protected $primaryKey = 'id';
public $timestamps = false;
public function sale()
{
return $this->belongsTo('App\Sale', 'sales_id', 'id');
}
public function product()
{
return $this->belongsTo('App\Product', 'product_id');
}
}
In the query above, I want to update all the switches to '0' from the salesdetails relationship. How can I do this one?

Since you are updating the SalesDetails and not the Sale, I would reverse the query so that the update is actually on the SalesDetails instead of the Sale:
Sales_details::whereHas('sale', function($query) use ($now){
$query->where(DB::raw("(DATE_FORMAT(transaction_date,'%Y-%m-%d'))"), '<', $now)
})->where('product_id', '<=', 24)->where('switch', 1)->update(['switch' => 0]);

What you are trying is wrong, You should try like this
Sale::where(DB::raw("(DATE_FORMAT(transaction_date,'%Y-%m-%d'))"), '<', $now)->salesdetails()->where('product_id', '<=', 24)->where('switch', 1)->update(['switch' => 0]);
I assume transaction_date column is in the Sale Model.

Related

Laravel get created_at value in model

I'm trying to fetch the created_at attribute in the model so I can put it in my relationship.
E.g. rows in exit_accession_goods created today should look at rows in entry_accession_goods that were made today or before it.
Here's what I've tried:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ExitAccessionGood extends Model
{
protected $fillable = ['exit_accession_id', 'norm_id', 'quantity'];
public function entry_goods()
{
return $this->hasMany('App\EntryAccessionGood', 'norm_id', 'norm_id')
->whereDate('created_at', '<=', $this->created);
}
public function packagings()
{
return $this->hasMany('App\PackagingItem', 'norm_id', 'norm_id');
}
public function getCreatedAttribute()
{
return "{$this->created_at}";
}
}
The $this->created returns an empty string.
Try this
public function getCreatedAttribute(){
return $this->attributes['created_at'];
}

Laravel Tables Join

I have three tables:
notes: id, business_id, note
businesses: id, title, description
businessimages : id, business_id, image
I get my customers notes with this:
$customer = Auth::guard('customer-api')->user();
$notes = Note::where('customer_id', $customer->id)->with('business:id')-
>orderBy('id', 'desc')->get();
Now I want to get notes.id, businesses.id, businesses.title, businesses.description, businessimages.image for each notes and show all of them in one json array
How could I do?
Note::where('customer_id',$customer->id)
->join('businesses', 'businesses.id', '=', 'notes.buisness_id')
->join('businessimages', 'businesses.id', '=', 'businessimages.buisness_id')
->select(notes.id, businesses.id, businesses.title, businesses.description,businessimages.image)
->get();
Note model;
public function business() {
return $this->hasOne('App\Business', 'business_id', 'id');
}
Business mode;
public function businessImage()
{
return $this->hasOne('App\BusinessImage', 'business_id', 'id');
}
Your controller;
$notes = Note::where('customer_id', $customer->id)->with('business.businessImage')->orderBy('id', 'desc')->get();
You should consider using API Resources
This is a great way to organize a model(or a collection of models as well).
App\Note
use Illuminate\Database\Eloquent\Model;
class Note extends Model
{
public function business()
{
return $this->belongsTo('App\Business');
}
}
App\Business
namespace App;
use Illuminate\Database\Eloquent\Model;
class Business extends Model
{
public function note()
{
return $this->hasOne('App\Note');
}
public function businessImage()
{
return $this->hasOne('App\BusinessImage');
}
}
App\BusinessImage
namespace App;
use Illuminate\Database\Eloquent\Model;
class BusinessImage extends Model
{
protected $table = 'businessimages';
public function business()
{
return $this->belongsTo('App\Business');
}
}
App\Http\Resources\Note
namespace App\Http\Resources;
class Note
{
public function toArray($request)
{
return [
'noteId' => $this->resource->id,
'businessId' => $this->resource->business->id,
'businessTitle' => $this->resource->business->title,
'businessDescription' => $this->resource->business->description,
'businessImage' => $this->resource->business->businessImage->image
];
}
}
Somewhere in a controller
use App\Http\Resources\Note as NoteResource;
public function foo()
{
$customer = Auth::guard('customer-api')->user();
$notes = Note::where('customer_id', $customer->id)->with(['business','business.businessImage'])->orderBy('id', 'desc')->get();
return NoteResource::collection($notes);
}

Relation isn't showed in query with Laravel

I have in model Report following
public function reportedItem()
{
return $this->belongsTo('App\Item', 'item_id', 'id');
}
In Item model
public function report()
{
return $this->hasMany('App\Report', 'item_id','id');
}
In controller
public function details( $item_id )
{
$flags = Item::find($item_id)->report->unique('user_id');
return view('flags.details', compact('flags'));
}
Why when I do {{ dd(collect($flags)) }} in my view.blade I don't see anything from items table even when I query it Item::find($item_id)?
dd output
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Report extends Model
{
protected $table = 'reports';
protected $primaryKey = 'report_id';
protected $fillable = [
'item_id', 'report_body', 'user_id', 'report_reason'
];
public function reportedItem()
{
return $this->belongsTo('App\Item', 'item_id', 'id');
}
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id');
}
}
One way is to use something like this in your controller
public function details( $item_id )
{
$flags = Report::with('reportedItem')->where('item_id', '$item_id')->get();
try this
$flags = Item::find($item_id)->with('report')->get()
The below should work
$flags = Item::with('reportedItem')->find($item_id);
Then when you dd($flags) this look for the "relations" tab and inside that you'll see the info.

Laravel 5: Eloquent whereHas subquery doesn't filter results

I'm trying to retrieve some results from a model using a relation and I'm trying to apply some filters on that relationship.
Here is the model:
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UserProduct extends Model
{
protected $primaryKey = null;
public $incrementing = false;
protected $table = "user_product";
public $fillable = [
...
"product_id",
"user_id",
"is_featured",
"is_hidden_from_latest"
...
];
public function product()
{
return $this->belongsTo("\\App\\Models\\Product", "product_id", "id");
}
...
}
and here is the related model:
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $table = "products";
public $timestamps = false;
public $fillable = [
...
];
public function userProduct()
{
return $this->hasOne("\\App\\Models\\UserProduct", "product_id", "id");
}
...
}
Here is the query on UserProduct model and product relationship:
$user_products = UserProduct::with("product")
->whereHas("product", function($q) {
$q->where("product_status", "live")
->where("parent_child", "Child");
})->where("is_featured", 1)
->orWhere("is_hidden_from_latest", 0)
->orderBy("is_featured", "desc")
->orderBy("updated_at")
->get();
The problem is that whereHas subquery doesn't seem to filter anything no matter what value to compare to I use for each product_status and parent_child.
Is there something that I don't do correctly?
Update: Seems that the game breakers are these two where() statements at the end:
....
->where("is_featured", 1)
->orWhere("is_hidden_from_latest", 0)
....
and more specifically the orWhere() statement.
Try this way
$user_products = UserProduct::with("product")
->whereHas("product", function($q) {
$q->where("product_status", "live")
->where("parent_child", "Child");
})
->where(function ($query) {
$query->where("is_featured", 1)
->orWhere("is_hidden_from_latest", 0);
})
->orderBy("is_featured")
->orderBy("updated_at")
->get();
I just removed where("is_featured", 1) and replaced it with just where("is_hidden_from_latest", 0) as I order the results ascendantly by is_featured anyway.
The whereHas() subquery works properly. :)

Laravel : Select from two tables where column in table two =value using eloquent

I have two tables
table 1 = NewsCollection
table 2 = NewsConllectionTranslation
here is the models
NewsCollection
class NewsCollection extends \Eloquent
{
use \Dimsav\Translatable\Translatable;
public $translatedAttributes = ['title', 'content'];
public $translationModel = 'NewsCollectionTranslation';
public function newsTrans()
{
return $this->hasMany('NewsCollectionTranslation', 'news_collection_id');
}
}
NewsConllectionTranslation
class NewsCollectionTranslation extends \Eloquent
{
public $timestamps = false;
protected $table = 'news_collection_translations';
protected $fillable = ['title', 'content'];
public function transNews()
{
return $this->belongsTo('NewsCollection', 'news_collection_id');
}
}
and here is the show controller
public function show($title)
{
$news = NewsConllectionTranslation::with('newsTrans')->where('title', $title)->first();
return View::make('portal.news.show', compact('news'));
}
What I need to do is
->where('title', $title)->first();
should be selected from NewsConllectionTranslation and I don't want to lose the translation so I don't want to select from NewsConllectionTrnslation first
You should try this:
$news = NewsConllectionTranslation::whereHas('newsTrans', function ($query) use ($title) {
$query->where('title', $title);
})->first();
Change your function like this
public function show($title)
{
$news = NewsConllectionTranslation::with(['newsTrans' => function ($query) use($title) {
$query->where('title', $title)->first();
}])
return View::make('portal.news.show', compact('news'));
}

Categories