How to access relation ID after saving in Laravel 4? - php

I have many-to-many relation between two models: movie and actor.
I need to obtain relation ID after saving it, to use it later. Here's the code:
$movie->actors()->save($actor); // it saves my relation
$relationID = 'how to obtain ID of new record in pivot table?';

I did it this way:
In Movie model:
public function actors()
{
return $this->belongsToMany('Actor')
->withPivot('id');
}
And I obtained ID this way:
$relationID = $movie->actors()
->where('actor.id', $actor->id)
->first()->pivot->id;
Ugly, but works. If it can be done any better, please let me know. :)

Related

Get data from multiple sql tables using eloquent with laravel

What i want to achieve?
Show user which pacts he is following.
What I am trying
I have designed two tables which are 'pacts' & 'pacts_follwers'
Table 'pacts' has the details of all the pacts
Table 'pacts_follwers' has details of users following a particular pact.
These links will give you the images of both the tables
For Schema Refer Images
So how to get pacts that user is following.
What I have tried?
Sql Query
SELECT pacts.*, (SELECT pactsid FROM pacts_follwers WHERE pacts.id = pacts_follwers.pactsid
and pacts_follwers.userid = 2 ) as pactID FROM `pacts`
Sql query Result
This query will give pactId some value, where the value is null means the user is not following that pact. If this is the solution then i would need Eloquent for this which i am unable to make.
1st table pacts
id
title
about
created_at
updated_at
pactsImage
2nd table pacts_follwers
id
pactsid
userid
created_at
updated_at
Controller Code
$pacts = DB::select("SELECT pacts.*, (SELECT pactsid FROM pacts_follwers WHERE pacts.id =
pacts_follwers.pactsid and pacts_follwers.userid = ".Auth::id()." ) as pactID FROM `pacts`");
You need to setup hasManyThrough relationship for User and Pact.
class User extends Model {
public function pacts() {
return $this->hasManyThrough(
Pact::class,
PactFollower::class
'userid',
'pactsid'
);
}
}
I don't fully understand if you want to achieve "get user's all pacts" or "if pact is followed by user". Either way, you need to setup related relationships.
Or really simple (and not efficient way)
class Pact extends Model {
public function followers() {
return $this->hasMany(PactFollower::class, 'pactsid')
}
}
Now you can use something like
$userIdsForPact = Pact::followers()->pluck('userid');
if ($userIdsForPact->has($user->id)) {
// your operation
}
Edit: For "if pact is followed by user", you need to setup belongsToThrough relationship. It doesn't come out of the box with Laravel but staudenmeir/belongs-to-through package should serve you well.
After setting the relationship properly, you can use something like this.
Pact::with('user')->get();
Or add some methods in your Pact model:
public function followedByUser($user) {
return $this->users->has($user);
}

collection to string in laravel 5.2 query builder

I want to make query in laravel 5.2 to fetch agencies table which has a foreign key with organizations table using agencies.organization_id=organizations.id. Now Users table has also foreign key with organizations table using users.organization_id=organizations.id. Now how to fetch agency table that which agencies are linked with users_id.
public function postagency(Request $request) {
$user_id = $request->user_id;
$org_id = User::where('id', $user_id)->pluck('organization_id')->first();
$postagencies = agency::where('organization_id', $org_id);
echo $postagencies;
}
For what I understand is that an user can only be under one organisation and an organisation has many agencies. If not please say so and I will alter my answer.
First of all set your relationships inside your models. An example would be:
// User.php
public function organization()
{
return $this->belongsTo('App\Organization'); // App\Organization can be changed depending on the used namespace
}
More info can be found here. If you need some more examples just ask.
After you have created these relationships you can retrieve your agency like this:
$user= User::find($request->user_id);
if (!$user) ... // Check if user exists
$agencies = $user->organisation->agencies;
If I need to explain things in more detail just ask. Hope this helps :)

Saving nested model laravel in one go

I have create two tables
AREAS
-id
-areaName
SOCIETIES
-id
-area_id
-societyName
My relationship is defined like this
class Area extends Model
{
//
public function society()
{
return $this->hasMany('App\Society');
}
}
class Society extends Model
{
public function area()
{
return $this->belongsTo('App\Area');
}
}
Now I have created objects for both area and society
$area = new \App\Area();
$area->areaName = $input['areaName'];
$society = new \App\Society();
$society->societyName = $input['societyName'];
$society->area()->associate($area);
After this when I call "$society->save()" its not saving any record and giving error area_id cannot be null. I want to save society and its relation area in one go.
When I use "$area->save()" before associate its saving the record when calling "$society->save()". All I want to do is skip "$area->save()" and save both society and area in one go.
It is giving you the error because you don't have a record in the database with an id for it. You need to save the area record first and then associate it with the relation. I don't think it will work other wise, take a look at eloquent docs on laravel's website:
https://laravel.com/docs/5.1/eloquent-relationships

Laravel: How to get single pivot row by key id

I have a many-to-many relation set on my User and Notification Eloquent models. This way I can access the pivot table - user_notifications - as follows:
$user = User::find(1);
foreach ($user->notifications() as $n) {
echo $n->pivot->created_at;
}
This will give me all created_at field values from the pivot table, for the user of ID = 1.
What if I need only one pivot row, let's say the one with notification_id = 2? Is there a way to combine pivot with where or has? Can it be done without looping through $user->notifications()?
You can use a where clause on the relationship:
$notification = $user->notifications()->where('notification_id', 2)->first();
echo $notification->pivot->created_at;
You can also directly use find method.
$notification = $user->notifications()->find(2);
echo $notification->pivot->created_at;
I've been dealing with this, and lukasgeiter's answer is fine, until the weird case where you want to find a pivot row by id (if you set up a $table->increments('id') column on the pivot table. I do this sometimes, but a better solution is to use a dedicated model for the relationship (Defining Custom Intermediate Table Models # https://laravel.com/docs/5.6/eloquent-relationships)
What you can do in this strange case:
$notification = $user->notifications()->having('pivot_id', 2)->first();
echo $notification->pivot->created_at;
You'll have to include withPivot('id') in your relationship method in the model. i.e.
function notifications() {
return $this->belongsToMany('App\Notification')->withPivot('id');
}

Database relationship name & best practice for it, in my laravel app

I have a database schema in my laravel app. In that schema, there are three models - Boss, Employee & Review.
A Boss can have many employees. An Employee can have many bosses(we can consider bosses from previous jobs). An Employee can Review his/her Boss. Boss can't Review anyone, so only Employee can review.
Thus, there are these relationships -
Employee & Boss has many-to-many relationship
Employee & Review has one-to-many relationship ( one Employee can Review multiple Bosses, thus having multiple reviews from his/her side ).
As you can see there is no direct relationship between Boss & Review. But, the query is -
What are the reviews for Boss 'x'?
To answer this query in laravel, I first thought that it had 'hasManyThrough' relationship. But, 'hasManyThrough' works only when Boss & Employee have 'one-to-many' relationship. That is, when one Boss can have multiple Employee but not vice-versa.
So, my question is - Is there a relationship which is applicable in this scenario(like polymorphic etc.)? If yes, how to use it in laravel?
No need for that extra table with reviews.
Here's all you need - first the tables:
bosses: id, ...
employees: id, ...
boss_employee: id, boss_id, employee_id, review (nullable), ...
Then the models:
// Boss model
public function employees()
{
return $this->belongsToMany('Employee')->withPivot('review');
}
public function reviews()
{
return $this->hasMany('Review');
}
// Employee model
public function bosses()
{
return $this->belongsToMany('Boss')->withPivot('review');
}
public function reviews()
{
return $this->hasMany('Review');
}
// Review model
protected $table = 'boss_employee';
public function boss() // or eg. reviewed
{
return $this->belongsTo('Boss');
}
public function employee() // or eg. reviewer
{
return $this->belongsTo('Employee');
}
Now, with this setup you can do this:
// get boss and his review
$boss = $employee->bosses->first();
$review = $boss->pivot->review;
// get review for given boss of an employee
$review = $employee->reviews()->where('boss_id', $bossId)->first();
// get bosses with reviews
$bosses = Boss::whereHas('reviews', function ($q) {
$q->whereNotNull('review');
})->get();
// and so on and so forth
You can enhance your Review model by adding global scope so it returns only the rows from boss_employee table having not null review field. This would be pretty much the same as SoftDeletingScope, but the conditions need to be swapped - by default whereNotNull, instead of whereNull in the SoftDeletingScope.

Categories