Get count form reations [Laravel 5] - laravel-5

I have realation like this below...
public function likesXp()
{
return $this->belongsToMany('App\Like', 'comment_like')
->withPivot('user_id')
->where('like_id',1)
->selectRaw('count(comment_like.like_id) as aggregate');
}
How can I get aggregate count from this relation?
I need to do something like this:
return Model::with('likesXp')->where('comments.user_id',1)->get()->aggregate;

Related

Get data through pivot table in Laravel

I got 3 tables. Table 1 & 2 has their ids as foreign keys in third one(pivot).
Relations for first one is
$this->hasMany("App\Pivot","game_id");
, second is
$this->belongsToMany("App\Pivot","army_id");
and pivot has relationships with both of them i.e belongsTo.
My schema:
I tried accessing it in controller of first one like this:
$games= Game::with("armies")->get();
Result that i get is array of games where instead of individual army data , i get collection from pivot table.
I can loop through it and get it that way, is there more elegant way of doing it?
If you are using pivot table this is the way how to do it.
Games Model
public function armies()
{
return $this->belongsToMany(App\Armies::class, 'pivot_table', 'game_id', 'army_id');
}
Armies Model
public function armies()
{
return $this->belongsToMany(App\Games::class, 'pivot_table', 'army_id', 'game_id');
}
Access the relationship like this..
Controller
App\Games::first()->armies()->get();
or
App\Games::first()->armies
or
App\Games::find(1)->armies
If you're going to use an intermediate table like that I'd probably do something like this:
Games model
public function armies()
{
return $this->belongsToMany('App\Armies');
}
Armies model
public function games()
{
return $this->belongsToMany('App\Games');
}
I'd keep the table structures all the same but rename the "pivot" table to armies_games since this is what Laravel will look for by default. If you want to keep it named Pivots, you'll need to pass it in as the second argument in belongsToMany.
With this, you don't really need the Pivot model, you should just be able to do:
$armies = Game::first()->armies()->get();
or
$armies = Game::find(3)->armies()->orderBy('name')->get();
or
$game = Game::first();
foreach ($game->armies as $army) {
//
}
etc.

Laravel Query to Many to many table with optional conditions

I have 3 tables as follow
dealer
id - dealer_name
specialties
id - name
dealer_specialty
id - dealer_id - specialty_id
So Dealer and Speciality model have many to many relation ship so in their models they looks like
Dealer.php
public function specialties()
{
return $this->belongsToMany('App\Models\Specialty');
}
In Speciality.php
public function dealers()
{
return $this->belongsToMany('App\Models\Dealer');
}
Now I have a scenario, where user can filter the result. Like at first whole dealers table will be shown. Now user can filter result with specialties and dealer name. So I have made route with optional parameters. And on my controller I am checking if param ins't empty put a where condition. Its working only with dealer_name as its where condition is referring to its own table. I got problem when I need to put where condition with specialty table.
My code looks like
$dealerArray = DB::table('dealers');
if(!empty($speciality )) {
// how to put where condition like get all dealers with specialit id 4, if this condition matches. I have tried following but its definitely generating error.
$dealerArray->specialities()->where('blah blah blah');
//I have also tried whereHas..
}
if(!empty($keyword)) {
$dealerArray->where('dealer_name','Like','%'.$keyword.'%');
}
return $dealerArray->get() ;
So finally I want to know how can I put an option condition that If I have to filter dealers from specialty id, how can I do that.
Try this one
In the Dealer.php
public function specialties()
{
return $this->belongsToMany(Speciality::class, 'dealer_specialty', 'dealer_id', 'specialty_id');
}
In Speciality.php
public function dealers()
{
return $this->belongsToMany(Dealer::class, 'dealer_specialty', 'specialty_id', 'dealer_id');
}
Query
$dealerArray = new Dealer();
if (!empty($speciality)) {
// how to put where condition like get all dealers with speciality id 4,
// if this condition matches. I have tried following but its definitely generating error.
$dealerArray = $dealerArray->whereHas('specialties', function ($query) use ($speciality) {
$query->where('specialty_id', $speciality);
});
//I have also tried whereHas..
}
if (!empty($keyword)) {
$dealerArray = $dealerArray->where('dealer_name', 'Like', '%' . $keyword . '%');
}
return $dealerArray->get();

Laravel 5 Pivot Table Extra Field

What I’m trying to do is when a new candidate is created an extra field is automatically populated in the joining pivot table with a random sting.
Here is my pivot table:
Result Table (pivot)
id cert_number candidate_id qualification_id
1 ? 17 2
2 ? 17 1
3 ? 57 1
So in my candidate controller I have:
public function store(CandidateRequest $request)
{
$candidateInput = Input::get('candidates');
foreach ($candidateInput as $candidate)
{
$candidate = Candidate::create($candidate);
$candidate->centre()->attach(Auth::user()->centre);
$qualification_id = $request->input('qualification_id');
$candidate->qualification()->attach($qualification_id);
$cert_number = Str::random(10);
$candidate->qualification()->attach($cert_number);
}
return redirect('candidates');
}
It adds the centre_id and qualification_id perfectly but it won’t pull though the random sting into the cert_nubmer field.
In my Candidate model I have
public function result()
{
return $this->hasMany('App\Result')->withTimestamps();
}
public function qualification()
{
return $this->belongsToMany('App\Qualification', 'Results', 'candidate_id', 'qualification_id')->withPivot('status','cert_number','partial_claim')->withTimestamps();
}
and in my result model:
public function candidate()
{
return $this->belongsTo('App\Candidate')->withTimestamps();
}
public function qualification()
{
return $this->belongsTo('App\Qualification');
}
Can anyone see where Im going wrong?
Thanks.
attach does not work like that.
Let me take out two lines of code:
$candidate->qualification()->attach($qualification_id);
$candidate->qualification()->attach($cert_number);
You are trying to add the $cert_number as a qualification_id, which is why it fails. When you do this, how is Laravel supposed to know that the second line ($cert_number) is an extra pivot column? It doesn't. You have two lines of code that are exactly the same so you can't expect Laravel to know that the second line should do something different.
When you want to insert extra data into other pivot columns, you need to pass them as an array in the second argument. Something like this:
$candidate->qualification()->attach($qualification_id, ['cert_number' => $cert_number]);

Laravel Has One Relation changing the identifier value

I'm not sure this is a real relation. I will try to explain the best way I can.
So first of all, I have three models :
Appartement,
AppartementPrice
The AppartementPrice depends on :
- appartement_id
I would like the AppartementPrice to be retrieve like that :
If there is a specific price for the appartement, then retrieve it, If not retrieve the price for all appartement which is stored in the database with an appartement_id = 0.
So basically what I would like is to do something like that :
public function price()
{
if(isset($this->hasOne('AppartementPrice')->price) // Check that relation exists
return $this->hasOne('AppartementPrice');
else
return $this->hasOne('AppartementPrice')->where('appartement_id', '0');
}
But this is not working.
It does not retrive me the default price.
I guess anyway this is not a best practice ?
I first tried to get the informations like that :
//Check if appartment has a specific price or retrieve default
if($priceAppartement = AppartementPrice::getPriceByCompanyAppartement($this->id))
return $priceAppartement;
else
return AppartementPrice::getDefaultPrice();
But I had this error :
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
when doing :
echo $app->price->price;
How can I check that a relation exists ? And is there a way to do as I describe ?
Thank you
You can't replace relation like this, as what you intend is not logical - you want to retrieve relation that doesn't exist.
Instead you can do this:
public function getPriceAttribute()
{
return ($this->priceRelation) ?: $this->priceDefault();
}
public function priceDefault()
{
// edit: let's cache this one so you don't call the query everytime
// you want the price
return AppartmentPrice::remember(5)->find(0);
}
public function priceRelation()
{
return $this->hasOne('AppartementPrice');
}
Then you achieve what you wanted:
$app->price; // returns AppartmentPrice object related or default one
HOWEVER mind that you won't be able to work on the relation like normally:
$price = new AppartmentPrice([...]);
$app->price()->save($price); // will not work, instead use:
$app->priceRelation()->save($price);
First of all something really important in Laravel 4.
When you do not use parentheses when querying relationship it means you want to retreive a Collention of your Model.
You have to use parentheses if you want to continue your query.
Ex:
// for getting prices collection (if not hasOne). (look like AppartementPrice)
$appartment->price;
// for getting the query which will ask the DB to get all
//price attached to this appartment, and then you can continue querying
$priceQuery = $appartment->price();
// Or you can chain your query
$appartment->price()->where('price', '>', 0)->get() // or first() or count();
Secondly, your question.
//Appartement Model
// This function is needed to keep querying the DB
public function price()
{
return $this->hasOne('AppartementPrice')
}
// This one is for getting the appartment price, like you want to
public function getAppartmentPrice()
{
$price_object = $this->price;
if (!$price_object) // Appartment does not have any price {
return AppartementPrice->where('appartement_id', '=', 0)->get();
}
return $price_object;
}

Laravel eager loading result

I'm having trouble with eager loading in laravel
I have these models:
class Page extends Eloquent {
public function translations() {
return $this->has_many('Pagestl', 'page_id');
}
}
and
class Pagestl extends Eloquent {
public static $table = 'pages_tl';
public function page() {
return $this->belongs_to('Page', 'id');
}
}
I want a specific page with its translation data of a specific language.
I retrieve the data like this:
$page_data = Page::with(array('translations' => function($query) {
$query->where('lang_id', '=', 'nl')->first();
}))->find($id);
De result is ok-ish. I get all the page data and the translation of 1 language, dutch (nl). But in order to get a field from the language data I have to this:
$page_data->translations[0]->attributes['content_or_whatever'];
..which i find ugly. I feel i should only have to do something like:
$page_data->translations->content;
..but that gives me an error (Trying to get property of non-object).
Am I missing something or is this just the way it is?
I don't find it necessary to do eager-loading here.
Both ways of doing it will result in 2 queries: select the Page with the given id and then find its first translation.
So, I would do:
$page = Page::find($id);
and then
$page_data = Pagestl::where_page_id_and_lang_id($page->id, 'nl')->first();
Then, assuming the content field exists in pages_tl table, we'll get it by doing:
echo $page_data->content;
Finally, your code looks alright; you don't have to have the second parameter when defining the relationships unless they are different from what Laravel expects.
I'll let you find where the problem is with your code (I couldn't figure out from the information given - could be something to do with strings.php)

Resources