I have the defaults users table which I've altered to have userable_type and userable_id. I have various models, eg BursaryAdministrator and BursaryProvider and users can belong to either.
BA/BP Model:
public function users() {
return $this->morphMany('App\Users', 'userable');
}
Users Model:
public function userable()
{
return $this->morphTo();
}
During my migration, I've created a default BursaryAdministrator and BursaryProvider and a couple of users. I want to assign them to each:
$bp = \App\BursaryProvider::first();
$user = User::find(2);
$bp->users()->associate($user);
$ba = \App\BursaryAdministrator::first();
$user = User::find(3);
$ba->users()->associate($user);
However, they're not linking as the userable_type / userable_id fields are null. I've tried both 'associate' and 'attach'.
Whats the correct what to do this?
You could try to save() the user after association, i.e.:
$bp = \App\BursaryProvider::first();
$user = User::find(2);
$bp->users()->associate($user);
$user->save()
$ba = \App\BursaryAdministrator::first();
$user = User::find(3);
$ba->users()->associate($user);
$user->save()
Ok, so this was the correct way at the end of the day:
$bp = \App\BursaryProvider::first();
$user = User::find(2);
$user->userable()->associate($bp);
$user->save();
$ba = \App\BursaryAdministrator::first();
$user = User::find(3);
$user->userable()->associate($ba);
$user->save();
Thanks to #dparoli for pointing me in the right direction.
Related
i'm having an error with Eloquent (and Many to Many relationship).
This is my code:
$user = new Users;
$rs = $user
->company()
->where('company_role.users_id', $request->session()->get('usrid'))
->where('code', $request->company)
->first();
The query that Eloquent perform is this one:
select `companies`.*, `company_role`.`users_id` as `pivot_users_id`, `company_role`.`companies_id` as `pivot_companies_id`, `company_role`.`role_name` as `pivot_role_name` from `companies` inner join `company_role` on `companies`.`id` = `company_role`.`companies_id` where `company_role`.`users_id` is null and `company_role`.`users_id` = 1 and `code` = 12345678901 limit 1)"
How is this possible? Do you guys have any idea?
This is my Users model:
class Users extends Model
{
//table associated with model
protected $table = 'users';
protected $primaryKey = 'id';
public function company(){
return $this->belongsToMany('App\Companies','company_role')->withPivot('role_name');
}
}
It was a rookie error
i just changed this:
$rs = $user->company()->where('company_role.users_id',$request->session()->get('usrid'))->where('code',$request->company)->first();
into this:
$rs = $user->find($request->session()->get('usrid'))->company()->where('piva',$request->company)->first();
and everything works as expected.
Thanks to everyone!
First, define the variables
$user_id = $request->session()->get('usrid');
$user = User::find($user_id);
Then, you need to find the user and the companies they are attached, and an individual company with the search params
$companies = $user->company()->get();
$company = $user->company()->where('code', $request->company)->first();
How to update a record in the related table model by chain expression?
This is what I currently do (and it works)
$user = User::find(1);
$token = Token::where('user_id', $user->id)->first();
$token->token = $request->token;
$token->save();
But can I do the above in a more elegant way, such as?
$user = User::find(1);
$user->token()->token = $new_token;
$user->token()->save();
My User Model
public function token()
{
return $this->hasOne('App\Token');
}
In one line:
User::find(1)->token()->update(['token' => $new_token]);
Just know these things before using it:
User find could return null if the user id is not found.
The saved and updated model events will not be fired for the updated models.
The update method execution does not go through the Eloquent model methods.
However in your particular case I think it's valid, specially if you know that the user id will always be valid.
Yo can do it like this :
User::find(1)->token()->update(['token' => $new_token]);
Or do it in youApp\Token class like this :
User::find(1)->token()->update_token($new_token);
And create update_token function in App\Token class:
public function update_token(string $new_token)
{
$this->update(['token'=>$new_token]);
}
$user = User::with('token')->findOrFail(1);
$user->token->update(['token' => $request->token]);
I am new to make join tables with Eloquent. I want to join 3 tables. But it shows me error. What's my mistake, if anyone notice it will be helpful for me. Here is tables....
In 1st table Applications(id,u_id,program_name) 2nd table StudentInfos(id,u_id,.....) 3rd table users(id,.....)
in Application model
public function StudentInfo()
{
return $this->hasOne('App\StudentInfo', 'u_id', 'u_id');
}
in StudentInfo model
public function User()
{
return $this->hasOne('App\user', 'u_id', 'id');
}
From controller
public function view_application($id)
{
$vu_data = Application::where('id', $id)->get();
$vu_data2 = $vu_data->StudentInfo()->get();
return $vu_data2;
}
$vu_data2 = $vu_data->StudentInfo()->get();
is returning a collection and not just a single Application Model. Change "get()" to "first()", and this will fix your first error. So change:
$vu_data = Application::where('id', $id)->get();
to
$vu_data = Application::where('id', $id)->first();
When you do get(), it returns a collection. You can do :
$vu_data = Application::findOrFail($id);
$student = $vu_data->StudentInfo;
$user = $student->User;
I'm trying to get associate to work.
Relationship on User model:
public function group()
{
return $this->belongsTo('User');
}
So I do:
$user = new User();
//save user fields
....
$user->save();
$group = Group::find(1);
$user->group()->associate($group);
A new user is inserted, but in the FK of group_id on the user table I am getting null.
Associate needs to be before save.
$user = new User();
//save user fields
....
$group = Group::find(1);
$user->group()->associate($group);
$user->save();
Well, let say you want to associate a comment with a blog post, because the comment can only be for a specific post we will use associate.
In our Post model we will have this:
public function comments(){
return $this->hasMany('App\Comment');
}
in our comment model we have this:
public function post(){
return $this->belongsTo('App\Post');
}
In our CommentsController we will have this:
$comment = new Comment;
$post=Post::find($post_id);
$comment->post()->associate($post);
$comment->save();
Pay attention that you save it only after you associate it with the post.
you need to save user after associating
$user->save();
full code
$user = User::create([
'field1' => $request->field1,
....
]);
$group = Group::find(1);
$user->group()->associate($group);
$user->save();
I'm trying to extract the building of an Eloquent query as I want to reuse this code with many different models. In the controller, I have:
$inputs = Input::all();
$user = new Eloquent;
$result = Helpers::buildQuery($user, $inputs);
And the Helpers class:
<?php namespace ArgumentClub;
class Helpers {
public static function buildQuery(Eloquent $model, $inputs)
{
$limit = isset($inputs['limit']) ? $inputs['limit'] : 10;
$offset = isset($inputs['offset']) ? $inputs['offset'] : 0;
list($orderCol, $orderBy) = isset($inputs['order']) ? explode(",", $inputs['order']) : explode(",", 'created_at,DESC');
$result = $model
->orderBy($orderCol, $orderBy)
->skip($offset)
->take($limit)
->get();
return $result;
}
}
So, how can I pass in the model and have it query that model, returning the Eloquent collection?
Eloquent (which is an alias for Illuminate\Database\Eloquent\Model) is an abstract class. You can't instantiate it. Instead you have to do this:
$inputs = Input::all();
$user = new User;
$result = Helpers::buildQuery($user, $inputs);
The type restriction buildQuery(Eloquent $model, $inputs) will still work fine because User extends Eloquent and therefore is accepted by the method.
A little sidenote, you might also want to think about creating a base model to extend Eloquent and share functionality between all models.
You just have to pass your model class for exemple a User model which extend eloquent:
$inputs = Input::all();
$user = new User;
$result = Helpers::buildQuery($user, $inputs);
Just add the ungaurd() and regaud() before and after your seeder classes in run() method of DatabaseSeeder.php
\Illuminate\Database\Eloquent\Model::unguard();
//$this->call(UsersTableSeeder::class);
\Illuminate\Database\Eloquent\Model::reguard();
This solved my problem.