Eloquent Table Relationships - mysql

Hello i just realized how very confused i am by these relations, I have a question i need to ask. Assuming i have two table with records.
Roles
Administrator
Manager
Employee
Users
User 1
User 2
User 3
Now i want to create a relationship between these two tables, in this situation each user can have only one role but how do i express this relation?
To be more specific is it the user row in the table that can have only one role or the users table as a whole?
If it is the users table as a whole that can have only one role then in a situation where User 1 and User 2 are both administrators will the relationship then become many to many?

You might start by reviewing the documentation on relationships in Laravel/Eloquent: http://laravel.com/docs/5.1/eloquent-relationships
Your classes will look something like this:
class User extends Model
{
public function role()
{
return $this->hasOne('App\Role');
}
}
class Role extends Model
{
}
This means that each User has one Role - it doesn't prevent the same role from belonging to multiple users.

I seems it will become.
Role model
public function users()
{
return $this->hasMany('App\User');
}
User model
public function role()
{
return $this->belongsTo('App\Role');
}
so means, a Role can have many users and a user belongs to a role.
so User1 and User2 can be both Administrators. Check out laracast for additional info on relationship

I think, will be better, to use ManyToMany in Role-User reations, because, if you want now to use one role for one user, in future, probably, you will need to user more than one role to user. Also, ManyToMany not slower, than One-to-Many, but it more powerfull decision.
Role model
public function users()
{
return $this->belongsToMany('App\User');
}
User model
public function role()
{
return $this->belongsToMany('App\Role');
}

Related

Multiple Foreign Key from the same table

I have a Laravel application with a MySQL database that has 3 tables: Publication, Comment and User.
When I display a publication to user I call WS GET Publication By Id and WP GET Comment By Publication Id to display all comments related to that publication.
I want to know if there's a way to avoid Calling WP GET User By Comment Id for each Comment, because when I display a comment I also need to display some information for user who commented.
Can I add multiple user Foreign Keys in table Comment and use them?
Thanks in advance.
This is a very generic usecase. Can you see if this answers your question.
Publication model{
whatever fields you have,
//Comments --> One to many relation with Comment model
public function comments()
{
return $this->hasMany('App\Comment');
}
}
Comment Model{
whatever fields you have,
//User --> One to one relation with User model
public function user()
{
return $this->hasOne('App\User');
}
}
User Model{
fields...
}
In your controller, you can get the publications with comments and users by using with function.
$pub = Publication::first()->with('comments.user');
I hope this helps.

MySQL database structure advice needed. Two many-to-many from one table to two other that are in one-to-many relation

I have this setup as my database structure which already works pretty well, but I feel like it could be better, but cannot figure out how.
Database Structure:-
Events can have multiple sub-events. Users can join these events and optionally their sub-events. With this structure I have all constraints, but the one that links the event attending with the sub event attendings => there can be sub event attendings left without having the main event attending (this shouldn't be possible as users who don't attend the main event cannot attend it's sub events).
I am currently working with Laravel so it looks like this:
User:
hasMany Event (as organizer of these events)
belongsToMany EventAttending (which events is a user joining)
belongsToMany SubEventAttending (which sub-events is a user joining)
Event:
belongsTo User
hasMany SubEvent
belongsToMany EventAttending (which users are attending this event)
SubEvent:
belongsTo Event
belongsToMany SubEventAttending (which users are attending this sub-event)
The problem arises when trying to manage the sub-event attendings of a user. How would I make this constraint between the event and sub-event attendings exist, while keeping it clean with the capabilities of Laravel / What can you give as advice for a better structuring / How would you guys do it?
Edit
To clarify, the events and sub-events store different things, have different properties. Also I need to store information for the event attendings (like did he attend in real life) and sub-event attendings, most likely differing ones.
Edit
Edward Haber has the better structure, but as my two pivot tables (the connection between User-Event and User-SubEvent) store additional diferent type of information, currently chose to remain with the initial design.
One of the biggest problems I am facing (which does exist with both structure) is querying for a User while getting the attended Events with the attended SubEvents. Trying to achive this result:
User[]:{
...,
attending_events[]:{
...,
attending_sub_events[]:{
...
}
}
}
Been thinking for hours for a clean solution, couldn't get anything else to work. Wouldn't like to write the whole SQL query manually. My current implementation with the two pivot table looks like this (result not nested, code messy):
$users = User::withCount(['attendingEvents' => function($query) use($eventId){
$query->where('event_id', $eventId);
}])
->with(['attendingSubEvents' => function($query) use($eventId){
$query->select('id')->whereHas('event', function($query) use($eventId){
$query->where('id', $eventId);
});
}]);
With this approach I get the sub-events separated from the main event. (querying only for the main attending-event count, because I only need to determine whether he is joining or not).
The pattern for this type of solution is to use a Polymorphic Relationship. This solution focuses just on connecting the User to the Event and SubEvent - the rest of the relations look correct.
<?php
class User extends Model {
public function attending() {
return $this->morphTo();
}
}
<?php
class Event extends Model {
public function attendees() {
return $this->morphMany('App\User', 'attending')
}
}
<?php
class Subevent extends Model {
public function attendees() {
return $this->morphMany('App\User', 'attending')
}
}
The users table needs these fields:
*users*
-----
id
attending_id
attending_type
This is all untested - but the basic idea. (Edited: changed name of polymorphic method to attending from attendee)

Laravel Database structure 'apply'

So I have a weird question.
I'm making an application in Laravel and Angular. I'm using Eloquent models.
Right now I have 2 tables, 1 users table (with the users info), and 1 events table (with the name, date, ... of an event).
These 2 are binded by a oneToMany relation (Every event belongs to an user). But now I would like people to sign up for that event. ( a switch in the front end, so they can apply for the event).
So, many users will have many events.
The catch is also, the owner of the event can manually set an maximum # users. (This is an tinyINt in my event table).
So now my question. How can I pull this off?
Options I have thought off:
1. I make a pivot table
-> Is this possible? Because the User and the event are already binded by a one to many realtion? So how can I bind them with a many to many relation again?
2. Every time a user signs op, I add his ID to an array in the events table.
-> Is this possible? I could then be able to set the maximum # users by checking the length of the array?
Thank you friends!
Using a pivot table is the correct approach here. The fact that the two tables are already bound by a different relation should not deter you.
class Events extends Eloquent
{
public function owner()
{
return $this->belongsTo(App\User::class);
}
public function subscribers()
{
return $this->belongsToMany(App\User::class, 'event_user');
}
public function canAddSubscriber()
{
if ( ! $this->max_users) return true;
return $this->max_users < $this->subscribers()->count();
}
}
As you can see, you can use the relationship to determine if a subscriber can still be added.

In hibernate how to set status for various table objects

I have two objects, Customer and Store. I would like a user (from a user table) to be able to specify a customer or store as "preferred". I would then be able to see a list of users who prefer different stores or customers. Is this possible with a hibernate mapping?
What would the table structure look if a status of preferred could be set on either customer of store per user?
So, a User has many preferred Stores, and a Store is the preferred store of many users. This is thus a ManyToMany association between User and Store.
Just map it as explained in the documentation:
public class User {
#ManyToMany
private Set<Store> preferredStores = new HashSet<Store>(0);
}
public class Store {
// necessary only if you want the association to be bidirectional:
#ManyToMany(mappedBy = "preferredStores")
private Set<User> preferringUsers = new HashSet<User>(0);
}

Using LINQ and Entity how do I return values of a many-to-many relationship

I have two entities, Account and Subscription with a many-to-many association between them. I can't seem to find in the tutorials anywhere how to do the following:
I want to find all the Accounts with a Subscription of type x. If I wasn't using the Entity framework I could join to the AccountSubscription table, but that isn't accessible via Entity. Do I have to create a special entity if I need to query on a many-to-many relationship?
EF should create a navigation property for a many-to-many relationship. Then you should be able to do something like this:
var accounts = from a in Accounts
where a.Subscriptions.Any(s => s.SubscriptionType == "something")
select a;
For example, I have a simple db with a many to many relationship between Products and Groups:
And EF creates the association in the model:
So I can create a query like this (here including the Groups so I can see the Category):
What about something like this:
List<Accounts> myAccounts = //get accounts;
foreach(Accounts a in myAccounts)
{
foreach(Subscriptions s in a)
{
//add it to a global list?
}
}