How to pass a parameter from a Laravel controller to a model hasmany function - eloquent

I have an app with categories and subcategories, and I need to translate all of them to multiple languages. I want to retrieve all of the categories with their subcategories, along with any translations that exist, using a leftJoin.
It's been impossible to find documentation on how to pass a parameter from the controller to the model's function. I've seen lots of (similar) suggestions on ways to get around it, but nothing that explains how to pass the parameter.
This is in the model:
public function subcats(){
return $this->hasMany('App\SongCategory','parent_id','id')->orderby('sort_order','ASC');
}
public function subcatwithtranslations($lang="es"){
return $this->hasMany('App\SongCategory','parent_id','id')->where('song_categories.language','en')
->leftJoin('song_category_translations',function ($join) use ($lang){
$join->on('song_categories.id', '=', 'song_category_translations.song_category_id') ;
$join->where('song_category_translations.language','=',$lang) ;
})
->select('song_categories.*', 'song_category_translations.id AS trans_id', 'song_category_translations.category_name AS translation')
->orderby('sort_order','ASC');
}
I can get all of the parent categories, with any translations that exist, along with all the subcategories (but missing any subcategory translations) this way:
$querys = SongCategory::with('subcats')
->where('parent_id',0)
->where('song_categories.language','en')
->leftJoin('song_category_translations',function ($join) use ($lang){
$join->on('song_categories.id', '=', 'song_category_translations.song_category_id') ;
$join->where('song_category_translations.language','=',$lang) ;
})
->select('song_categories.*', 'song_category_translations.id AS trans_id', 'song_category_translations.category_name AS translation')
->OrderBy($orderby,$dir);
When this is in the controller:
$querys = SongCategory::with(['field', 'song_categories.subcatwithtranslations($lang)'])
->where('parent_id',0)
->where('song_categories.language','en')
->leftJoin('song_category_translations',function ($join) use ($lang){
$join->on('song_categories.id', '=', 'song_category_translations.song_category_id') ;
$join->where('song_category_translations.language','=',$lang) ;
})
->select('song_categories.*', 'song_category_translations.id AS trans_id', 'song_category_translations.category_name AS translation')
->OrderBy($orderby,$dir);
I get "Call to undefined relationship [field] on model [App\SongCategory]. RelationNotFoundException.php
If I do it this way as some have suggested as an alternative to passing the parameter to the model:
$querys = SongCategory::with(array('subcatwithtranslations'=>function($query) use ($lang){
$query->where('song_category_translations.language',$lang); // This pre-filters the subcats and breaks the left join
}))
->where('parent_id',0)
->where('song_categories.language','en')
->leftJoin('song_category_translations',function ($join) use ($lang){
$join->on('song_categories.id', '=', 'song_category_translations.song_category_id') ;
$join->where('song_category_translations.language','=',$lang) ;
})
->select('song_categories.*', 'song_category_translations.id AS trans_id', 'song_category_translations.category_name AS translation')
->OrderBy($orderby,$dir);
Then the leftJoin for the subcategories to their translations is negated before we even start, and I only get the subcategories that are already translated.
If I try to get the subcategories with translations, without even passing the language, but hard-coding it in the model via the default, like this:
$querys = SongCategory::with('subcattranslations')
->where('parent_id',0)
->where('song_categories.language','en')
->leftJoin('song_category_translations',function ($join) use ($lang){
$join->on('song_categories.id', '=', 'song_category_translations.song_category_id') ;
$join->where('song_category_translations.language','=',$lang) ;
})
->select('song_categories.*', 'song_category_translations.id AS trans_id', 'song_category_translations.category_name AS translation')
->OrderBy($orderby,$dir);
I get an error, Collection::addEagerConstraints does not exist
How do I pass the parameter to the model function so that I can do a left join?

Related

How to implement a join in a join with Eloquent

I have a question how to combine two joins in Laravel's eloquent. One join also belongs to the other.
The concept is you have timeslots and I want to know how many attendees there for that timeslot.
The challenge is: I want all available timeslots and a booking is only valid when it's done live, not canceled and completed.
With the query below the booking and counting part is fine, but I only get the timeslots with bookings done.
$this->selectRaw('timeslots.id, timeslots.time_from , timeslots.time_till, duration_minutes,
count(attendees.id) as bookedSlots,
capacity as total,
capacity - count(attendees.id) as leftTickets')
->where('timeslots.project_id', $projectId)
->where('invoices.type', '!=', 'IncompleteOrder')
->whereDate('time_from', '=', $date)
->leftJoin('attendees', function($query) {
$query->on('timeslots.id', '=', 'attendees.timeslot_id')
->where('attendees.is_live', '=', 1)
->where('attendees.is_cancelled', '=', 0);
})
->leftJoin('invoices', 'attendees.invoice_id', '=', 'invoices.id')
->groupBy('timeslots.id')
->get();
This was a/the solution:
$response = $this->selectRaw('timeslots.id, timeslots.time_from , timeslots.time_till, duration_minutes,
count(attendees.id) as bookedSlots,
capacity as total,
capacity - count(attendees.id) as leftTickets')
->where('timeslots.project_id', $projectId)
->whereDate('time_from', '=', $date)
->leftJoin('attendees', function($query) {
$query->on('timeslots.id', '=', 'attendees.timeslot_id')
->where('attendees.is_live', '=', 1)
->where('attendees.is_cancelled', '=', 0);
})
->leftJoin('invoices', function($query) {
$query->on('invoices.id', '=', 'attendees.invoice_id')
->where('invoices.type', '!=', 'IncompleteOrder');
})
->groupBy('timeslots.id')
->get();

how to show only last record with query builder in laravel

I only want to display the latest data from the tanggal_ins that I have marked, how to?
This is my json data:
And this is my query:
$cuti = DB::table('t_cuti as cuti')
->join('m_karyawan as kary', 'kary.nik', '=', 'cuti.nik')
->join('m_rumah_sakit as rs', 'rs.kd_rs', '=', 'kary.kd_rs')
->join('m_unit as unit', 'unit.kd_unit', '=', 'kary.kd_unit')
->join('m_jabatan as jab', 'jab.kd_jabatan', '=', 'kary.kd_jabatan')
->leftJoin('t_cuti_adjust as adj', function ($leftJoin) {
$leftJoin->on('adj.nik', '=', 'cuti.nik')
->latest();
})
->select('adj.tanggal_ins','cuti.saldo_cuti','kary.nik','kary.nm_karyawan','rs.nm_rs','unit.nm_unit','jab.nm_jabatan')
->whereYear('adj.tanggal_ins', '<', $year)
->orWhere('adj.tanggal_ins', null)
->get();
Thanks.
Use orderBy.
->orderBy('id', 'desc')->first();
This will make descending order by ID.
->orderBy('id', 'desc')
and use first() instead of get().

Laravel nestedwhere Parse error: syntax error, unexpected '}'

Symfony\Component\Debug\Exception\FatalThrowableError: Parse error: syntax error, unexpected '}'
I followed this resources for nested where here: How to combine WHERE clauses in Eloquent but get the following error while running the codes. The line where it broke was the curly bracket of the callback function, what's wrong here?
$providers = DB::table('users')
->where('verified', '=', 1)
->where('status', '=', 1)
->where(function ($query) use ($search) {
$query->where(DB::raw('lower(name)'), 'LIKE', "%".strtolower($search)."%")
->orWhere(DB::raw('lower(username)'), 'LIKE', "%".strtolower($search)."%")
})
->where('city', '=', $t)
->take($limit)
->toSql();
You are missing a ;after your inner $query. I think that part could be this:
->where(function ($query) use ($search) {
$query->where(DB::raw('lower(name)'), 'LIKE', "%".strtolower($search)."%")
->orWhere(DB::raw('lower(username)'), 'LIKE', "%".strtolower($search)."%");
})
The code needs that semicolon at the end, because it is a line / statement in a function. It does not matter that this function is a callback.

Fix Mongo query in Lumen

I have a query in the lumen. But it does not work. The query is :
return Order::whereBetween('source_longitude', [$minLon_try_one, $maxLon_try_one])
->whereBetween('source_latitude',[51.365807806703,51.454384193297])
->where('status','=','pending')
->where('created_at','<=', 2016-04-07 12:00:35)
->where('created_at','>=', 2016-04-07 11:55:35)
->orWhere(function($query)
{
$query->whereBetween('source_longitude', [51.321519613407, 51.498672386593])
->whereBetween('source_latitude',[35.612195271526,35.756086728473])
->where('status','=','pending')
->where('created_at','<=',2016-04-07 11:55:35)
->where('created_at','>=',2016-04-07 11:50:35);
}
)->get();
But when I remove orWhere function from the query I get expected result
You probably using orWhere a little bit wrong. You need to put where to another where to execute query properly. What You are doing now is something like that where a is 1 and b is 2 or (c is 3 and d is 4), but I believe, You want to do something like that where (a is 1 and b is 2) or (c is 3 and d is 4)
Try this one:
return Order::where(function ($query) {
$query->whereBetween('source_longitude', [$minLon_try_one, $maxLon_try_one])
->whereBetween('source_latitude', [51.365807806703, 51.454384193297])
->where('status', '=', 'pending')
->where('created_at', '<=', '2016-04-07 12:00:35')
->where('created_at', '>=', '2016-04-07 11:55:35');
})->orWhere(function ($query) {
$query->whereBetween('source_longitude', [51.321519613407, 51.498672386593])
->whereBetween('source_latitude', [35.612195271526, 35.756086728473])
->where('status', '=', 'pending')
->where('created_at', '<=', '2016-04-07 11:55:35')
->where('created_at', '>=', '2016-04-07 11:50:35');
})->get();

[Symfony\Component\Debug\Exception\ContextErrorException]

I'm making fixtures and when I try to load them I have an error. The relationship between Award and Movie is unidirectional, so I load first Award because it hasn't any reference. The error says:
[Symfony\Component\Debug\Exception\ContextErrorException] Warning: spl_object_hash()
expects parameter 1 to be object, array given in
/Users/benatespina/Development/filmboot.web/vendor/doctrine/mongodb-odm/lib/Doctrine/ODM‌/MongoDB/UnitOfWork.php line 1706.
This is my Fixture class:
namespace MyProject\MovieBundle\DataFixtures\MongoDB;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use MyProject\MovieBundle\Document\Award;
class Awards extends AbstractFixture implements OrderedFixtureInterface {
public function load(ObjectManager $manager) {
$awards = array(
array(
"name" => "Sitges",
"year" => "1992",
"category" => "Best director"
);
foreach ($awards as $i => $award) {
$document = new Award();
$document->setName ($award["name"]);
$document->setYear ($award["year"]);
$document->setCategory($award["category"]);
$manager->persist($document);
$this->addReference("award-" . $i, $award);
}
$manager->flush();
}
public function getOrder() {
return 1;
}
}
This exception has nothing to do with symfony2 or doctrine-fixtures - it's a generic PHP exception.
You are trying to use a variable $i that has never been defined in your addReference() call.
$this->addReference("award-" .$i, $award);