Im new to this laravel eloquent so bare with me. Im doing a search function for Payment. everything is doing fine, until i need to inner join a table Contract for me to output $payment->contract->account_no in a search result.
i just need to convert this SQL to eloquent (i only included account_no since its the column that i need get in Contract)
SELECT
tbt_contracts.account_no , tbt_payments.payment_type, tbt_payments.payment_mode, tbt_payments.payment_date, tbt_payments.payment_amount, tbt_payments.payment_due_date,
tbt_payments.payee_name
FROM tbt_payments
INNER JOIN tbt_contracts ON tbt_payments.contract_id = tbt_contracts.id
WHERE tbt_contracts.account_no LIKE '%test%'
Payment Model
public function contract()
{
return $this->belongsTo(Contract::class);
}
Contract Model
public function payments()
{
return $this->hasMany(Payment::class);
}
Payment Controller (when i click the search button)
$filters = [];
//account_no (ERROR)
!is_null($request->account_no) ? array_push($filters, ['account_no', 'like','%'.$request->account_no.'%']) : null;
//payment_type
!is_null($request->payment_type) ? array_push($filters, ['payment_type', 'like','%'.$request->payment_type.'%']) : null;
//payment_mode
!is_null($request->payment_mode) ? array_push($filters, ['payment_mode', 'like','%'.$request->payment_mode.'%']) : null;
//payee_name
!is_null($request->payee_name) ? array_push($filters, ['payee_name', 'like','%'.$request->payee_name.'%']) : null;
return view('transaction.payment.paymentlist', [
'payments' => Payment::where($filters)->orderBy('id')->paginate(10),
'payment_modes' => LogicCONF::getDropDownJson('payment_mode.json'),
'payment_types' => LogicCONF::getDropDownJson('payment_type.json'),
]);
working code (works without table join, errors with table join)
return view('transaction.payment.paymentlist', [
'payments' => Payment::where($filters)->orderBy('id')->paginate(10),
]);
DB Facade:
I tried DB Facade. my problem with it is i cannot use or call Public Function inside my payment model. (i haven't even tried joining the tables)
$payments = DB::table("tbt_payments")->orderBy('id')->paginate(10);
done.
for some reason innerjoin dont work,
also thanks to this SQLtoEloquent
$payments = Payment::with("contract")
->leftJoin("tbt_contracts", function($join){
$join->on("tbt_payments.contract_id","tbt_contracts.id");
})
->where($filters)
->select('tbt_payments.*')
// ->groupBy("tbt_payments.id")
->orderBy('tbt_payments.id')
->paginate(10);
Related
I want to integrate a two tables order and orderdetails table with an id of ord_id. My code is not working.
public function orderview()
{
$orderid = $this->uri->segment(3);
$data["order"]=$this->db->join('tbl__order', 'tbl__order_detail.ord_id = tbl__order.ord_id',$Query=' where ord_id='. $orderid);
$this->load->view('manage/orderpayment/view',$data);
}
Are you ever work with Codeigniter before?
Your Model function must look like this. Call this function from your Controller to return data, then you can process this data and send it to your View.
public function orderview(){
$orderid = $this->uri->segment(3);
$this->db->select('tbl__order.*, tbl__order_detail.ord_id as tbl__order_id');
$this->db->from('tbl__order');
$this->db->join('tbl__order_detail', 'tbl__order_detail.tbl__order_id = tbl__order.ord_id');
$this->db->where('tbl__order.ord_id', $orderid);
return $this->db->get()->result_array();
}
In "join" you can use as third argument left, right, outer etc.
I have 3 Tables:
Customers
id
name
Sales
customer_id
sale_date
Contacts
customer_id
contact_date
There aren't any update operations in the contacts table. Each process opens a new record in the contacts table. So, a user can have more than one records in the contacts table.
Here are my relations in models:
Customer
public function contacts()
{
return $this->hasMany(Contact::class);
}
public function sales()
{
return $this->hasMany(Sale::class);
}
Contact
public function customer()
{
return $this->belongsTo('App\Customer', 'customer_id');
}
Sale
public function customer()
{
return $this->belongsTo('App\Customer');
}
I would like to have the latest record of the contacts table and make it join with the other related tables.
Here is the query which I have tried:
$record = Contact::groupBy('customer_id')
->select(DB::raw('max(id)'));
$result = Customer::query();
$result->where('is_active', 'YES');
$result->with('sales');
$result->whereHas('contacts', function ($q) use($record){
return $q->whereIn('id', $record)->where('result', 'UNCALLED');
});
return $result->get();
In the blade file, I get some result in foreach loops. However, I am unable to get the related data from the sales and contacts table.
#foreach($result as $item)
#foreach($item->sales as $sale) // Has no output and gives error: Invalid argument supplied for foreach()
#foreach($item->contacts as $contact) // Has no output and gives error: Invalid argument supplied for foreach()
Can anyone help me how to display the sale and contact date? Or any idea for how to improve this code quality?
If you want the latest record of the contacts you can declare another relationship on the Customer model, e.g.:
public function latest_contact()
{
return $this->hasOne(Contact::class)->latest('contact_date');
}
BTW you can always declare one or more hasOne additional relationship if you have a hasMany in place the foreign key used is the same.
In this way you can retrieve latest_contact eager loaded with your Customer model:
$customer = Customer::with('latest_contact')->find($id);
Or use this relationship in your queries, something like that:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->whereHas('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
Or that:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->with('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
If you want you can declare last_contact with the additional where:
public function latest_contact()
{
return $this->hasOne(Contact::class)
->where('result', 'UNCALLED')
->latest('contact_date');
}
This way all other queries should be easier.
I hope this can help you.
I'm not sure, but can you try to do the following:
return Customer::where('is_active', 'YES')
->with([
'sale',
'contact' => function ($query) use($record) {
return $query->whereIn('id', $record)->where('result', 'UNCALLED');
}
])->get();
Laravel Version: 5.6.39
PHP Version: 7.1.19
Database Driver & Version: mysql 5.6.43
Description:
When I chain where and orWhere in a model accessor to count related model , I get wrong result and here is my query. the count is returned strange result without filtering by the calling event id,
class Event extends Model
{
protected $table = 'events';
public function registrations()
{
return $this->hasMany('App\Components\Event\Models\Registration','event_id','id');
}
public function getSeatsBookedAttribute()
{
return $this->registrations()
->where('reg_status','=','Confirmed')
->orWhere('reg_status','=','Reserved')
->count();
}
}
Steps To Reproduce:
the following queries return me the expected results, however In my knowledge the first query should return the same result if i am not wrong, so i think this is a potential bug.
class Event extends Model
{
public function getSeatsBookedAttribute()
{
return $this->registrations()
->whereIn('reg_status', ['Confirmed', 'Reserved'])
->count();
}
}
class Event extends Model
{
public function getSeatsBookedAttribute()
{
return $this->registrations()
->where(function($query){
$query->where('reg_status','Confirmed')
->orWhere('reg_status','Reserved');
})
->count();
}
}
and here is the query dump,
here is the query when I donot explicit group it.
"select count(*) as aggregate from events_registration where (events_registration.event_id = ? and events_registration.event_id is not null and reg_status = ? or reg_status = ?) and events_registration.deleted_at is null "
and here is the query when i group it explicitly,
select count(*) as aggregate from events_registration where events_registration.event_id = ? and events_registration.event_id is not null and (reg_status = ? or reg_status = ?) and events_registration.deleted_at is null
The reason this happens is because you're chaining where() and orWhere(). What you don't see behind the scenes is a where event_id = :event_id applying to your query. You end up with a query that looks something like this:
select * from registrations where event_id = :event_id and reg_status = 'Confirmed' or reg_status = 'Reserved'
In normal SQL you'd want to put the last 2 conditions in parentheses. For Eloquent, you'd need to do something like this:
return $this->registrations()->where(function ($query) {
$query->where('reg_status', 'Confirmed')
->orWhere('reg_status', 'Reserved');
});
You can chain the toSql() method on these chains to see the difference. Note, that in this case, I believe whereIn() is the semantically correct thing to do.
Eloquent can handle this for you, though; scroll down to "Counting Related Models" in the Querying Relations part of the Eloquent Relationships docs:
$posts = App\Event::withCount([
'registrations as seats_booked_count' => function ($query) {
$query->where('reg_status','Confirmed')
->orWhere('reg_status','Reserved');
}
])->get();
I want to show the company list with distinct is there's a way using eloquent? this code isn't working
public function create()
{
$goods = goods::all();
$company = company::all()->distinct('name')->get();
return view('pages.purchaseCreate',['goods' => $goods, 'company' =>$company]);
}
this are the error message
Method Illuminate\Database\Eloquent\Collection::distinct does not exist.
That's because all() returns a collection. This should work:
$company = company::distinct('name')->get();
I have an Eloquent ORM relationship defined as follows:
ProductConfiguration:
public function product()
{
return $this->belongsTo('Excel\Products\Product');
}
public function currency()
{
return $this->belongsTo('Excel\Currencies\Currency');
}
Product
public function productConfigurations()
{
return $this->hasMany('Excel\Products\ProductConfiguration');
}
public function productType()
{
return $this->belongsTo('Excel\Products\ProductType');
}
I expect that if I do the following that I will load all product configurations of a specified product type, with the related products, nested product type details and the product configuration currency
$results = ProductConfiguration::with(
array(
'product' => function($query) use ($product_type) {
$query->where('product_type_id' , $product_type);
},
'product.productType',
'currency'
)
)
->get();
however the returned collection has 'product' set to NULL. the Currency Relationship is there, but the product relationship is not. I can see the outputted SQL queries and the query that selects the products retrieves the correct products if I paste it directly into my sql editor
select * from `products`
where `products`.`id` in ('12', '13')
and `product_type_id` = '1'
Am I correct to think that the results from this query should be included in my collection, or is there some obvious flaw in my thinking?
I think you don't want to achieve that. Now what you get is getting all ProductConfiguration with products that are only of certain_type.
So in case you have some configuration that has other type for product you will get null because you limited results from product to only the one that has certain product type.
I might be wrong, but you probably wanted to get those ProductConfiguration that belongs to Product that is type of certain_type. In this case you should use whereHas:
$results = ProductConfiguration::
with('product', 'product.productType', 'currency')->
whereHas('product', function($q) use ($product_type)
{
$q->where('product_type_id', '=', $product_type);
})->get();
I hate to post this as an answer but since i don't have enough rep to comment so try this first:
$results = ProductConfiguration::with('product')->get();
dd($results->toArray());
See what you get, if you get some data, try this
$results = ProductConfiguartion::with(array('products' => function($query){
$query->where('product_type_id' , $product_type);
})->get();
dd($results);
See what you get, if you get null: your $product_type variable may be something you didnt expect, so try dd($product_type) to make sure its what your expecting.