How to change value in hasOne related table in Laravel? - laravel

I can't figure this out and I know it's so basic ;-)
I have two tables, user and userInfo. The relationship is one-to-one, very simple. How can I update userInfo? This is code from the end of my UserSeeder:
// after seeding, change the 1st user to always be the same
$user = User::first();
$user->name = 'admin';
$user->email = 'test#mysite.test';
$user->userInfo()->first()->AccountStatus = 1;
$user->save();
It runs without failing but userInfo doesn't set the user's AccountStatus = 1.
What am I missing?!! ;-)
Also: why do I have to do userInfo()->first() when there's always only one userInfo record connected to the user?
p.s. this is NOT a duplicate of How to update related table in Laravel? -- that's for many-to-many relationship... this is one-to-one.

Related

Get records from two relations (one is pass through accessor) with paginate

Laravel 7.x
I need to get posts from two relations. Look:
User has Posts;
User has Friends (accessor);
Friends has Posts;
How can I get all own (User) posts and all posts by each Friend, and paginated?
Which the best way to do that?
Only to pass the idea that I want to say:
$user = User::find(1);
$posts = $user->with('posts','friends.posts')->paginate(15); // I wanna get only the Posts collection
I would suggest query your Post model and then apply filter for user and related friends filter.
$user = User::with('friends')->find(1);
$userIds = $user->friends->pluck('id')->toArray();
array_push($userIds, $user->id);
$posts = Post::whereIn('user_id', $userIds)->paginate(15);
You can use hasManyThrough, this relationship is a bit complicated to understand a provide shortcut way to access data of another mode relation.
In your User model make relationship like this way :
public function posts()
{
return $this->hasManyThrough(
Post::class,
Friend::class,
'user_id', // Foreign key on friends table...
'friend_id', // Foreign key on posts table...
'id', // Local key on users table...
'id' // Local key on friends table...
);
}
Now you can get all posts from User model like this way :
$user = User::find(1);
$posts = $user->with('posts')->paginate(15);

Laravel unique validation on update not working by passing id in validation

In my controller i am inserting data in three different table at a time.
I have put validation before inserting in some of the unique fields. But at the time of Update it says email already exists. I have searched a lot and got a solution which is working for everyone except for me by passing id in validation rule.
I have tried
$this->validate($request,[
'admission_no'=>"required|unique:students,admission_no,$id",
'student_email=>"required|unique:students,student_email,$id",
'guardian_email'=>"required|unique:student_parents,guardian_email,$id"
]);
$student = Student::find($id);
$student->admission_no = $request->admission_no;
$student->student_email = $request->student_email;
$student->save();
//parent model
$parent = StudentParent::where('student_id',$student->id)->first();
$parent->guardian_email = $request->guardian_email;
$parent->save();
It doesn't work this way i dont know why
also the main problem is StudentParent model is different how to pass id in validation for this model to unique update
Your students and student_parents table has different $id, So you need to pass student_parents table id on guardian_email validation :
$validatedData = $request->validate([
'admission_no'=>"required|unique:students, admission_no, $id", // expect students table id
'student_email'=>"required|unique:students, student_email, $id", // expect students table id
'guardian_email'=>"required|unique:student_parents, guardian_email, $student_parents_id" // pass student_parents table id here
]);
Hope this helps

Laravel adding data to pivot table while inserting new record

I have three tables,
roles(id, name);
users(id, email, password);
user_role(id, user_id, role_id);
In this scenario, I have users table is associated to roles table with many to many relation.
I have two eloquent model as
Role
+users(){
belongsToMany('User')
}
User
+roles(){
belongsToMany('Role')
}
Now, the question is when I want to add a new user along with ids of roles that I would like to assign to users. How can I insert values to pivot table with Laravel best practices?
My existing code is:-
$roles = Input::get('roles'); // arrays of role ids
$user = new User();
$user->username = Input::get('username');
$user->password = Hash::make(Input::get('password'));
$user->save();
What to do next???
It's really all described in the documentation.
Anyway, here's how you do it:
$user = new User();
$user->username = Input::get('username');
$user->password = Hash::make(Input::get('password'));
$user->save();
$user->roles()->attach($roles);
The important part is that you have to save the user before attaching (using attach()) the roles because otherwise the user doesn't have an id yet to be used in the pivot table.

Laravel mass update

yesterday i asked a question about Eager Loading and Form Model Binding.
Laravel Eager Loading and Form Model Binding
This is somehow a followup question.
Now i want to update the record in the Database
$user = \User::findOrFail($id);
$user->fill(\Input::all());
$user->push();
But this dose only save the data of the user itself. Not the relations
user = saved
user->profile = not saved
on my user model i have a fillable array with all fillables columns. and on other models like the profile model i just wrote protected $fillable = ['*'];
The Soultion:
call fill() on the relations not just the user model.
$user->fill($input)
$user->profile->fill($input['profile'])
You're not retrieving profile with your user model.
$user = \User::with('profile')->findOrFail($id);
That should give you the profile properties to update.

How to query relationships in Laravel 4 with Eloquent?

Coming from CodeIgniter's Datamapper ORM I am still trying to get my head around Laravel's Eloquent ORM.
Given the fact that I have an ACCOUNT and a USER table (simplified):
ACCOUNT
- id
- name
USER
- id
- account_id
- username
One account has many users. One user belongs to one account. So we're dealing with a one-to-many relationship. Everything is already set-up in the models.
In CodeIgniter's Datamapper I would have done the following to get the user from any given ID and at the same time check if that user is related to the current account:
$u = new User();
$u->where('username', $username);
$u->where_related_account('id', $account_id);
$u->get();
if ( ! $u->exists()) exit; // or do something...
// otherwise continue to use the "$u" user object
This syntax is very logical and easy to understand. In Eloquent I have a hard time to achieve the same with a similar easy syntax. Does anyone have any suggestions?
Very simply (ignoring the relationship between the user and the account), it could just be:
$u = User::where('username', $username)
->where('account_id', $id)
->get();
That will return you your user's details.
Otherwise, assuming that you have your User and Account classes and DB tables are set up correctly (as per the Laravel docs), you should be able to just do:
$user_exists = Account::find($account_id)
->users()
->where("username", "=", $username)
->first()
->exists;
if ($user_exists)
{
doThings();
}
If you've correctly set up your models and database tables (as #msturdy said) you should actually be able to return your user account by simply going:
$user = User::whereUsername($username)
->first(); // or User::where('username', $username)->first();
if ($user) {
$account = $user->accounts()
->whereId($account_id)
->first(); // or $user->accounts()->where('id', $account_id)->first();
}
This gives you the ability to access the user and account models
you could even extend your User model to include the following methods:
class User extends Eloquent {
...
public static function byUsername($username) {
return static::whereUsername($username)->first();
}
public function getAccount($id) {
return $this->accounts()->whereId($id)->first();
}
...
}
and then simply go
$user = User::byUsername($username);
if ($user) {
$account = $user->getAccount($account_id);
}
which might be better for you if you are using the code in multiple controllers.

Resources