Laravel 5 Model relationships - laravel-5

I just want to make sure that I am handling my relationships correctly. In my database, I have foreign constraints set up. I have a users table and a departments table. A user can only be apart of one department. However, a department can have many users. So in User.php, I have
public function department()
{
return $this->belongsTo('App\Department');
}
And then in Department.php I have
public function user()
{
return $this->hasMany('App\User');
}
Does this represent the relationship I am after?
Thanks

Yes, this is correct for a one-to-many relationship.
The only thing I would change is user() to users() as there are "many" users.
Lastly, just make sure that in you users table you have a column called department_id, otherwise you will have to tell laravel explicitly which column name you're after.
Hope this helps!

Related

Laravel BelongsTo relation - where on instance attribute

I have the following model:
class Order extends Model
{
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'shipping_email_address', 'email_address')
->where('customer_id', $this->customer_id);
}
}
Now when I call Order::with('user')->get(), it doesn't load the users.
I can access the user just fine when using Order::first()->user.
Is it possible to eager load a relationship with a where clause on a model instance attribute (like $this->customer_id)? Or is there another way to make a relationship based on two columns?
You can do this :
Your relation :
public function user()
{
return $this->belongsTo(User::class);
}
Then you can make query like this :
$userId = 5;
$result = Order::whereHas('user',function($q) use ($userId){
return $q->where('id',$userId);
});
Reply to your comment:
Having this relation :
public function user()
{
return $this->belongsTo(User::class);
}
Use this :
Order::with('user')->get()
This will retrieve all orders with its users. If you have some problem on that query then you have a wrong relationship. Make sure you have a foregin key in Orders table, if you dont espcify some foreign key on eloquent relationship, eloquent will understand than foreign key is : user_id, if not, especify putting more arguments to this function :
$this->belongsTo(User::class,...,...);
With function make join according to relationship configuration, just make sure the relation is ok. And all work fine !
If you want to keep your current flow, i would do it like so. Thou the josanangel solution is most optimal.
When getting orders include them using with. All these are now eager loaded.
$orders = Order::with('user');
Now utilize eloquent getters to filter the user by customer_id. This is not done in queries, as that would produce one query per attribute access.
public function getUserByCustomerAttribute() {
if ($this->user->customer_id === $this->customer_id) {
return $this->user;
}
return null;
}
Simply accessing the eloquent getter, would trigger your custom logic and make what you are trying to do possible.
$orders = Order::with('user')->get();
foreach ($orders as $order) {
$order->user_by_customer; // return user if customer id is same
}
Your wrong decleration of the relationship here is what is making this not function correctly.
From the laravel's documentation:
Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with a _ followed by the name of the parent model's primary key column. So, in this example, Eloquent will assume the Post model's foreign key on the comments table is post_id.
in your case the problem is that laravel is searching for the User using user_id column so the correct way to declare the relation is
public function user()
{
return $this->belongsTo(User::class, 'customer_id'); // tell laravel to search the user using this column in the Order's table.
}
Everthing should work as intended after that.
Source: documentation

Laravel:Many to Many Relationship

Hello Am trying to create many to many relationship but I failed. I have two table requests_table and Users_table and the relationship is many to many I introduce associative table called request_user with attribute of user_id, request_id and user_reqId(primary key). what I want is to submit data(user_id and request_id) to the associative entity when user request for anything?. help please....
Many-to-many relations are slightly more complicated than hasOne and hasMany relationships. An example of such a relationship is a user with many roles, where the roles are also shared by other users. For example, many users may have the role of "Admin". To define this relationship, three database tables are needed: users, roles, and role_user. The role_user table is derived from the alphabetical order of the related model names, and contains the user_id and role_id columns.
Many-to-many relationships are defined by writing a method that returns the result of the belongsToMany method.
Happy coding:)-
You should try this:
request_tbl.php
public function users() {
return $this->belongsToMany(User::class, 'request_user');
}
user.php
public function requests()
{
return $this->belongsToMany(RequestTbl::class, 'request_user');
}
Controller
$request_tbl = new requests_table();
$users = $request->users;
$request_tbl->users()->sync($users);

Eloquent hasOne vs belongsTo degenerate to same function if both keys are specified?

For the case of a one-to-one relationship, if I fully specify the keys in the method calls, is there a difference between hasOne and belongsTo relationships? Or, asked differently, if I used hasOne on both sides of the relation, would it be the same result?
Yes it works for some cases to specify the keys and make the relation work. And with some cases I mean mainly retrieving results. Here's an example:
DB
users profiles
----- --------
id id
etc... user_id
etc...
Models
Using "wrong" relations with hasOne twice
class User extends Eloquent {
public function profile(){
return $this->hasOne('Profile');
}
}
class Profile extends Eloquent {
public function user(){
return $this->hasOne('User', 'id', 'user_id');
}
}
Queries
Let's say we wanted to get the user from a certain profile
$profile = Profile::find(1);
$user = $profile->user;
This is working. But it's not working how it's supposed to be. It will treat the primary key of users like a foreign key that references user_id in profiles.
And while this may work you will get in trouble when using more complicated relationship methods.
For example associate:
$user = User::find(1);
$profile = Profile::find(2);
$profile->user()->associate($user);
$profile->save();
The call will throw an exception because HasOne doesn't have the method associate. (BelongsTo has it)
Conclusion
Whereas belongsTo and hasOne may behave similar in some situations. They are clearly not. More complex interactions with the relationship won't work and it's nonsense from a semantic point of view.

A many to many relationship

I've read the docs on relationships and have a few questions.
I have a user and a role table. The relationship is many to many. A user has many roles and a role can belong to many users. So I have set up a pivot table and have used a belongsToMany in each model. But surely a user hasMany roles and a role belongsToMany users.
But when I use hasMany, my queries do not work as expected. Is this just a wording thing and both should be belongsToMany?
I also wanted to know about defining the relationship on each model - do you need to or can it just be defined on users?
The hasMany relationship is for defining one to many relationships and that is why it will break your queries.
I can see why you are thinking along the lines of a user having many roles, but it also perfectly good English to say a user belongs to many roles and that a role belongs to many users.
You don't need to define the relationship on both models if you are only going to query one model and it's relationship. But can you say definitively that you will never need to query the relationship on roles?
I advice to you, study this description:
http://scotch.io/tutorials/php/a-guide-to-using-eloquent-orm-in-laravel
It will be useful for you.
(You should use only "belongToMany" in each model without "hasMany")
User model:
// app/models/User.php
<?php
class User extends Eloquent {
// each user BELONGS to many role
// define our pivot table also
public function roles() {
return $this->belongsToMany('Role', 'users_roles', 'user_id', 'role_id');
}
}
Role model:
// app/models/Role.php
<?php
class Role extends Eloquent {
// DEFINE RELATIONSHIPS --------------------------------------------------
// define a many to many relationship
// also call the linking table
public function users() {
return $this->belongsToMany('User', 'users_roles', 'role_id', 'user_id');
}
}

Where do i define the juncion table in many-to-many relationship in Laravel's Eloquent?

Here in the eloquent i see the Many to Many relationship:
http://laravel.com/docs/eloquent
I am not using Migrations and made two tables 'users' and a table 'roles' in phpmyadmin.
They both have a 'id' and 'name' column. Now i made the following models:
class User extends Eloquent {
public function roles()
{
return $this->belongsToMany('Role');
}
}
class Role extends Eloquent {
public function users()
{
return $this->belongsToMany('User');
}
}
My first question is. Do is still need to make junction table in phpmyadmin?
And if yes how do i tell Eloquent that (for example 'users_roles') is my junction table?
You must indeed have the table, and you can either follow Laravel conventions or specify it manually in the call to $this->belongsTomany();. Both ways are documented in the Eloquent documentation. The convention is in alphabetical order and singular table names (roles, users, role_user). To specify it in the call you can specify all sorts of things: return $this->belongsToMany('ForeignModel', 'pivot_table', 'local_id', 'foreign_id');
Yes, you still need to create the table.
In your models, add the table name as a second argument to belongsToMany.

Resources