Model Relationships not finding the property - laravel

I'm trying to create a relationship between two models. My first model is the User Model, the second one is Company.
I tried adding in the User model the hasMany('App\Comapny') property, and in the Company one, belongsTo('App\User').
// In User Model
public function companies(){
return $this->hasMany('App\Company');
}
// In Company Model
public function user(){
return $this->belongsTo('App\User');
}
// And in the controller:
$user_id = auth()->user('id');
$user = User::find($user_id);
return view('devices.show')->with('companies', $user->companies);
It should return an array with all the companies that my User has when using "$user->comapnies", however, it returns this message instead:
Property [companies] does not exist on this collection instance.
Thanks, any help is welcome

Thanks for the quick response. I figured it out, the problem was this line:
$user_id = auth()->user('id');
It should be instead
$user_id = auth()->user()->id;

Try this,
$user_id = auth()->user->id;
$user = User::with('companies')->where('id', $user_id)->first();
return view('devices.show', compact('user'));
Then you can access the company relation with
$user->company[index]->
in the view.

Related

Associate on create?

A user has many posts. A post belongs to one user.
The relationship on the post model is:
public function user()
{
return $this->belongsTo(User::class);
}
But when I want to use create and also associate a user, I get a call to undefined method error...
$user = \App\Models\User::find(10);
$post = Post::create($request->validated());
$post->associate($user);
How can I use create and then associate a user?
You forgot to call the user() method before calling associate().
$user = \App\Models\User::find(10);
$post = Post::create($request->validated());
$post->user()->associate($user);
$post->save();
Or even better, associate the user before saving the post so only one query is executed:
$user = \App\Models\User::find(10);
$post = new Post($request->validated());
$post->user()->associate($user);
$post->save();

How to retrieve all related models in a many to many relationship Laravel?

I am trying to retrieve all related models with another model through an intermediary table but can't figure out how. The Laravel docs say you can do something like this:
$roles = App\User::find(1)->roles()->orderBy('name')->get();
But when I try to apply that to my code
$roles = User::where('id', $user->id)->roles()->get();
It does not work. I am accepting the user model through my controller, so I do have access to it.
The relationship is also defined like so:
User
public function roles()
{
return $this->belongsToMany(Role::class);
}
Role
public function users()
{
return $this->belongsToMany(User::class);
}
How can I get all of the roles associated with a particular user?
edit/update:
I know I can simply use a foreach loop and get all of the roles associated with a particular user, but I am trying to return a resource collection, so I cannot do it that way
Try this,
I am assuming that $user_id is the parameter which is passed into the controller from the URL,
$roles=User::findOrFail($user_id)->roles;
But before running the above code, I assume that you have created the pivot table for many to many relationship with columns user_id and role_id. And have named the pivot table as role_user.
Hope this works
the problem with your second approach is calling roles() function on an 'Eloquent Query Builder' instance. You need to make sure to call roles() function on a 'User Model'.
this part of code User::where('id', $user->id) doesn't return a 'User Model'.
To get an 'User Model' from a 'Query Builder' instance you need to call first() function.
possible solution.
$roles = User::where('id', $user->id)->first()->roles;
The reason why you're getting the errors, is because before calling the method first() (or find() or findOrFail()), the instance is a QueryBuilder. and the roles() method exist only on an User::class instance.
if you are trying to get the user with an attribute roles containing a collection (array) of all his roles do:
$user = User::where('id', $user->id)->with('roles')->first();
if you need just the array of roles, you have two choices;
either get the user and then get his roles:
$user = App\User::find($userId);
$roles = $user->roles()->orderBy('name')->get();
//the same as
$roles = App\User::find($userId)->roles()->orderBy('name')->get();
or get the Roles (only one query)
$roles = Role::whereHas('users', function($users) use($userId) {
$users->where('id','=',$userId);
})->get();
Hope this gives you enough insight to build the exact code you need.
User
use App\User;
public function roles()
{
return $this->belongsToMany('App\Users', 'user_id');
}
Role
use App\Roles;
public function users()
{
return $this->belongsToMany('App\Roles');
}
Controller
$roles = User::where('id', $user->id)->roles()->get();
Try this one. I think your relationship is not correct.
You can read more information here Many To Many
You can use the following solution to retrieve all related models in a many to many relationship in Laravel:
$roles = User::where('id', $user->id)->get();
foreach($roles as $rol){
$rol->roles;
}

detach() in pivot table

Can't figure out how to delete record from pivot table.
I have users that belongsToMany documents with pivot document_user table.
here is my attach method:
public function share(Request $request, $company_id, $id)
{
$document = Document::find($id);
$user = $request['user'];
$document->users()->attach($user);
flash('Document has been shared!');
return back();
}
But how to make detach function? Should I build a form for this and what function should be? Something like $document->users()-detach($user). I have tried this, but doesn't work
You can do this in a couple ways:
First, you can use the detach() functionality (requires a second function in your controller). An example using a similar format to the one you provided:
public function unshare(Request $request, $id)
{
$document = Document::findOrFail($id);
$userId = $request['user']; //Assuming this is the User ID
$user = User::findOrFail($userId);
$user->documents()->detach($document->id);
flash('Document has been detached!');
return back();
}
Second, you can create a single function that toggles the association. Essentially you send a Document ID and if it is already associated to the User then it is Detached, if it is NOT associated to the User then it will Attach.
public function share(Request $request, $id)
{
$document = Document::findOrFail($id);
$userId = $request['user']; //Assuming this is the User ID
$user = User::findOrFail($userId);
$user->documents()->toggle($document->id); //This can also be an array of IDs
flash('Document has been toggled!'); //You might want to pass something or look up the association if you want custom messaging for attach or detach
return back();
}
Hope this helps!

How to retrieve only those object and its related model which passes the required criteria in laravel4?

I have three tables: users, departments and designations
I have created corresponding model for 'users', 'designations' and 'departments' table.
Relationship between table is:
User model
public function department(){
return $this->belongsTo('Department');
}
public function designation(){
return $this->belongsTo('Designation');
}
--
Department model
public function users(){
return $this->hasMany('User');
}
--
Designation model
public function users(){
return $this->hasMany('User');
}
Now, how would I query (in an eloquent way) to retrieve all the users that belongs to only specified department (say, 'account' department only).
I tried eager loading as well, but since there were two models that have to be fed with, it was more confusing.
I have a code as below, but now working. Help me to find the mistake
$users = new User;
$users = $users->department()->where('dept_code', '=', 'account')->get();
return View::make('staffs', compact('users'));
Here are two ways to do it:
1. From the Department side
$department = Department::where('dept_code', 'account')->first();
$users = $department->users;
2. From the User side using whereHas
$users = User::whereHas('department', function($q){
$q->where('dept_code', 'account');
})->get();
(Of course you can also use them like $users = new User; $users->where(, but I prefer the static call syntax so I use them in my examples)
You define a relationship with the constant. Like this:
User model
public function department(){
return $this->belongsTo('Department');
}
public function accounts_department(){
return $this->belongsTo('Department')->where('dept_code', 'account');
}
Then you use it like this
$all_users = new User;
$all_users = $all_users->department()->get();
$account_only_users = new User;
$account_only_users = $account_only_users ->accounts_department()->get();

Saving related records in laravel

I have users, and users belong to a dealership.
Upon user registration, I'm trying to save a new user, and a new dealership.
User database has a dealership_id column, which I want to be populated with the ID of the newly created dealership.
This is my current code in the UserController store method.
public function store()
{
$user = new User();
$user->email = Input::get('email');
$user->password = Input::get('password');
$dealership = new Dealership();
$dealership->name = Input::get('dealership_name');
$user->push();
return "User Saved";
}
Trying to use $user->push(); User data gets updated, but dealership is not created or updated.
Eloquent's push() saves the model and its relationships, but first you have to tell what you want to be involved in the relationsship.
Since your user-model/table holds the id of the dealership, I assume that a user can belong to only one dealership, so the relationship should look like this:
User Model:
public function dealership()
{
return $this->belongsTo('Dealership');
}
Dealership Model:
public function users()
{
return $this->hasMany('User');
}
To save a User from the Dealership perspective, you do this:
$dealership->users()->save($user);
To associate a dealership with a user, you do this:
$user->dealership()->associate($dealership);
$user->save();
Please check this answer to see the difference of push() and save()
You will need to define correctly your models relationships as per documentation
If this is done correctly, it should work .
This is what push() does :
/**
* Save the model and all of its relationships.
*
* #return bool
*/
public function push()
{
if ( ! $this->save()) return false;
// To sync all of the relationships to the database, we will simply spin through
// the relationships and save each model via this "push" method, which allows
// us to recurse into all of these nested relations for the model instance.
foreach ($this->relations as $models)
{
foreach (Collection::make($models) as $model)
{
if ( ! $model->push()) return false;
}
}
return true;
}
In your case, you have a one (dealership) belongs to many (users)
In your Users model :
class Users extends Eloquent {
public function dealership()
{
return $this->belongsTo('Dealership');
}
}
In the example above, Eloquent will look for a dealership_id column on the users table.
In your Dealership Model :
class Dealership extends Eloquent {
public function users()
{
return $this->hasMany('User');
}
}
In your store function :
public function store()
{
$user = new User();
$user->email = Input::get('email');
$user->password = Input::get('password');
$user->dealership = new Dealership();
$user->dealership->name = Input::get('dealership_name');
$user->push();
return "User Saved";
}
Learn here more about eloquent relationships
Also please take a look at my answer here
By using push on the User model, Laravel is basically recursively calling save on all the related models (which, in this case, is none, since you haven't associated any other models to it yet).
Therefore, in order to accomplish what you're trying to do, you can do first create the user then associate the dealership with it by doing the following:
$user = new User();
$user->email = Input::get('email');
$user->password = Input::get('password');
$user->save();
$dealership = new Dealership();
$dealership->name = Input::get('dealership_name');
$user->dealerships()->save($dealership);
return "User Saved";
However, prior to doing this, you must ensure your User and Dealership models have their relationships set up correctly:
User Model:
public function dealership()
{
return $this->belongsTo('Dealership');
}
Dealership Model:
public function users()
{
return $this->hasMany('User');
}
This is how I manage to do it.
In your controller: (Laravel 5)
use Auth;
$dealership->user = Auth::user()->ref_user->staff_id;

Resources