Get the ID of the last attached model - laravel

I try to get the last ID of an attached model ?
My code is the following to attach the model :
$menu->pages()->attach($element['page_id'], array('name' => $element['name'], 'order' => $i, 'menu_page_id' => NULL));
But after that, I want to know the ID of the attached model because I have a foreign key "menu_page_id" which is related to the same model.
Any idea how to do that or another way ?
Thanks

This is untested, but I don't see any reason why it wouldn't work.
$menu_page_id = $menu->pages()->wherePivot('page_id', $element['page_id'])->first()->pivot->menu_page_id;
Edit:
I just verified and this does indeed work for you, but only as long as you have your pages relationship setup like so...
public function pages()
{
return $this->belongsToMany('Page')->withPivot('menu_page_id');
}
Or if you don't want to do that, this should work too...
$menu_page_id = $menu->pages()->withPivot('menu_page_id')->wherePivot('page_id', $element['page_id'])->first()->pivot->menu_page_id;

Related

BackPack CRUD Select Title But Save ID

Here is an example of what I am trying to do (I have PRO version and DevTools incase anyone needed to know):
Lets say I have a CRUD setup for People.
In the List I have the School the Person is assigned to.
In the People CRUD I want to be able to Search for a "Name" of the School the person goes to but when selected and saved the CRUD will just store the School ID associated so its a relation.
Then on the list view it will showcase the School Name but again in the database only stores the ID and goes and fetches the Name. I am sure this is really easy to do but I cannot seem to find documentation on this as an example.
I have checked the docs and good as best as I can but not been able to find any documentation on it so any info or links would be great!
In your People model you should have the relationship setup like:
public function school()
{
return $this->belongsTo('App\Models\YourSchoolModel', 'school_id');
}
So you should define your columns like:
public function setupListOperation()
{
$this->crud->addColumn([
'name' => 'school',
'searchLogic' => function ($query, $column, $searchTerm) {
$possibleSchools = SchoolModel::where('school_name', 'LIKE', '%'.$searchTerm.'%')->pluck('id');
return $query->orWhereIn('school_id', $possibleSchools);
},
]);
You can check other examples here: https://backpackforlaravel.com/docs/5.x/crud-columns#custom-order-logic-for-columns
Cheers

Laravel - Delete and save in one query

In my app users can vote on submissions.
I first run a delete query for that submission to prevent any duplicate votes, then I save the vote:
SubmissionVote::where('submission_id', $submission->id)->where('user_id', Auth::user()->id)->delete();
$submissionVote = new SubmissionVote;
$submissionVote->submission_id = $submission->id;
$submissionVote->user_id = Auth::user()->id;
$submissionVote->vote = $vote;
$submissionVote->save();
Would it be possible to write this as one query to minimize overall database queries?
Or perhaps there's a way in the table migration to make it so that every submission_id can only have unique user_ids?
You could do this in a neater way like so:
Create a proper relation on the User model:
// models/User.php
public function submissionVote()
{
return $this->belongsTo(SubmissionVote::class);
}
then simply use this single statement in your controller:
Auth::user()->submissionVote()->updateOrCreate([
'vote' => $vote,
]);
This automatically updates the current user's submission OR creates a new one if it doesnt exist yet. Note that you have to use ->submissionVote() (query instance) vs ->submissionVote (model instance) so that you can use the query functions like updateOrCreate(). There are others available like firstOrCreate() or firstOrNew() which do slightly different things but are extremely handy shortcuts.
See https://laravel.com/docs/8.x/eloquent#upserts for more information.
Yes, it perhaps.
Schema::create('submission_votes', function (Blueprint $table) {
$table->unique([
'submission_id',
'user_id',
]);
});
And, update existing model:
SubmissionVote::query()->updateOrInsert(
['user_id' => Auth::user()->id, 'submission_id' => $submission->id],
['vote' => $vote]
);

Laravel eloquent query with sum of related table

I have a table users and posts with columns user_id and post_views.
In post_views I keep information how many times post was display.
And now, in query I would like to get user with sum of post_views all his posts.
I tried do something like this:
User::where(['id'=>$id])->with('posts')->get();
And in model I defined:
public function posts()
{
return $this->hasMany('App\Models\Post')->sum('post_views','AS','totalViews');
}
But without success.
How to do it?
Thank you
You can use a modified withCount():
public function posts()
{
return $this->hasMany('App\Models\Post');
}
$user = User::withCount(['posts as post_views' => function($query) {
$query->select(DB::raw('sum(post_views)'));
}])->find($id);
// $user->post_views
You can use
User::withCount('posts')->find($id)
to get the user with the id $id and a posts_count attribute in the response
I'm not fully sure what the intention of ->sum('game_plays','AS','totalVies'); is - you would need to add more context if you want this
Just something to add with regards to your shown code: No need to query by id using where + the get() at the end will make you query for a collection. If you want to get a single result use find when searching by id
As always laravel has a method for that : withSum (Since Laravel v8)
Note : I know that at the time of the message was posted, the method did not exist, but since I came across this page when I was looking for the same result, I though it might be interesting to share.
https://laravel.com/docs/9.x/eloquent-relationships#other-aggregate-functions
In your case it should be :
$user = User::withSum('posts as total_views', 'post_views')->find($id);
Then you can access to the result :
$user->total_views

Update Table Using Laravel Model

I've got a table for a sports team. The record shows the team selection and some other information. I want to update the record with the team selection. My model is thus:
class Selection extends Model {
protected $table = "selection";
protected $fillable = [
'loose',
'hooker',
'tight',
'secrow1',
'secrow2',
'blindflank',
'openflank',
'eight',
'scrum',
'fly',
'leftwing',
'rightwing',
'fullback',
'sub1',
'sub2',
'sub3',
'sub4',
'sub5'
];
}
So I have a form which gives all the data for the positions and gives the id for the record in the DB. In my controller, I've got:
public function storeFirstTeam()
{
$input = Request::all();
Selection::update($input->id,$input);
return redirect('first-team');
}
But I get the following error:
Non-static method Illuminate\Database\Eloquent\Model::update() should not be called statically, assuming $this from incompatible context
Can anyone point out my silly error?
Please check the code below and this would solve your problem:
Selection::whereId($id)->update($request->all());
The error message tells you everything you know: you’re trying to call a method statically (using the double colons) that isn’t meant to be.
The update() method is meant to be called on a model instance, so first you need to retrieve one:
$selection = Selection::find($id);
You can then can the update() method on that:
$selection->update($request->all());
You should write it like given example below:
Selection::where('id', $input['id'])->update($input);
// Or use this using dynamic where
Selection::whereId($input['id'])->update($input);
Alternatively, you may write it like this as well:
Selection::find($input['id'])->fill($input)->save();
You can also simply update the fields manually:
Selection::whereId($id)->update($request->all());
it is possible to update with primary key but in my case I dont have id field in the detail table. To do it just run a query like this:
DB::table("shop_menu_detail")
->where(['name' => 'old name', 'language' => 'english'])
->update(['name' => 'new name']);
where is used as it is.

Laravel 4 One To Many relationship Error

I am laravel newbie and I am trying to follow the documentation.So I have two models, 'User' model and a 'UserPhone' model. A user has many phones.
User model:
public function userPhone() {
return $this->hasMany('UserPhone');
}
UserPhone model:
public function user(){
return $this->belongsTo('User');
}
On my controller I am trying to "copy" the documentation:
$userPhone = User::find(1)->userPhone;
Well the result is an error:
Trying to get property of non-object
I know that I am missing something here , but I cannot find it.
I'm pretty sure that you don't have an user with id of 1.
$userPhone = User::find(1)->userPhone;
This should work, but, if it doesn't find the user the first part:
User::find(1)
I will return a NULL and NULL is not an object, then you get the error: Trying to get property of non-object.
My advice is, try to do this
var_dump( User::find(1) );
And you if you receive just a NULL, you found the problem.
Well the answer is that everything was ok!
I had accidentaly left
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
before the UserPhone Model Class declaration..It was such a newbie mistake.
If you want to fetch Users with their related phone numbers (userPhone) you can use Eager Loading.
//get all users (User) with their respective phonenumbers (userPhone)
$users = User::with('userPhone')->get()
//get User with id==1, with his related phonenumbers (userPhone of User(1))
$user_1 = User::with('userPhone')->where('id',1)->first()
and than you can do
if(!is_null($user))
$phones_of_user_1 = $user_1->userPhone();
else
$phones_of_user_1 = array();
That way, if a user of id==1 exists, you fetch his phone numbers. Else, you get an empty array and no exception/error (trying to get property on a non-object) thrown .
That relationship would automatically be loaded for you.
$user = User::find(1);
echo $user->userPhone->id;
This is assuming you have your database tables are setup correctly according to laravel's conventions and you actually have a User with an ID of 1.
1) You are missing a pair of () after userPhone
$userPhone = User::find(1)->userPhone();
2) You are not using the 'find' method properly. I think what you want to do is :
$userPhone = User::userPhone()->get();
or
$userPhone = User::find($phoneId); //where $phoneId is the id of the phone you are trying to find.
The 'find' method return only one object and will try to find it with it's id.

Resources