Laravel relation between 3 tables? - laravel

I have following tables:
users (classic laravel table)
events
user_events
in user_events I insert assigned users to events, the table structure is so:
Schema::create('user_events', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
$table->integer('event_id')->unsigned();
$table->foreign('event_id')->references('id')->on('events')->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
I want to create a page for auth user with his events.
To get Id's I use following relation in Model User:
public function userEvents() {
return $this->hasMany('App\Models\UserEvent');
}
Trought controller I get a list of Event id's.
My previous sources are:
Laravel relation between 3 models
Laravel 5 relation between 3 tables
Laravel Eloquent Relation between 3 table
My question is, what is here to do to get throught this event id's event names?

You could pluck the name from collection returned by $user->userEvents :
$user->userEvents->pluck('name');
Hope this helps.

By looking at your schema the relation should be many-to-many instead of one-to-many.
So your relation in User model looks as:
public function events()
{
return $this->belongsToMany('App\Models\Event');
}
Then in your controller, get all the events of authenticated user by:
$events = auth()->user()->events; // returns collection of Event model

Related

Laravel 5.7 - Users/followers pivot table to create a follower (user) to Bug relationship

This app has a Bug model and a User model. Users can "follow" Bugs. This seems like a pivot table. What's the simplest way to implement this with a migration and Model relationship? I'm thinking along the lines of a followers table:
Schema::create('followers', function (Blueprint $table) {
$table->increments('id');
$table->uuid('bug_id');
$table->uuid('user_id');
$table->index(['bug_id', 'user_id']);
$table->timestamps();
$table->softDeletes();
});
Where I'm mostly stumped is the followers relationship in the Bugs Model. This is where I'm currently at:
public function followers()
{
return $this->belongsToMany(User::class, 'followers', 'bug_id', 'user_id');;
}
This really doesn't seem right. New to eloquent pivot tables, so really appreciate the help!
You are looking for a many-to-many relationship which requires an intermediary table bug_follower just as you created one and you also need to create a relationship from Bug to Follower as you did, but also create the relationship from Follower to Bugs. You are on the right track.
Overall you will have 2 models: Bug, Follower.
You will also have 3 tables: bugs, followers, bug_follower
And 2 relationships from Bug and Follower to each other
EDIT: This is how your relationship needs to look like:
public function followers()
{
return $this->belongsToMany(User::class, 'followers', 'bug_id', 'user_id');
}
You can check more about subject in the docs.

belongsTo not returning results as desired

I would like to a user be able to only have one distrito (it means district in Portuguese). A distritocan have more than one user. It's a fairly simple relationship but the problem comes when you have a third table called distritosthat it's only job is to translate numbers into strings (I don't know the name of such tables).
Distrito table
$table->increments('id');
$table->string('distrito');
e.g.
ID DISTRITO
1 - Aveiro
2 - Beja
3 - ...
User tables
$table->string('name');
$table->string('last_name');
$table->string('profile_picture')->default('default.jpg');
$table->string('userProfile')->default('');
$table->float('stars')->default(0);
distrito_user table this table will reference where the user live
$table->integer('user_id'); //id of the user
$table->integer('distrito_id'); //Id of the district where the user lives
User's model
public function distritoUtilizador(){
return $this->belongsTo(DistritoUser::class);
}
DistritoUser's model
protected $table = 'distrito_user';
Calling the eloquent model
$user = Auth::user();
dd($user->distritoUtilizador);
It returns null.
First question: Is this the correct way to solve my problem (the user lives somewhere and I need to fill that location)?
If this is the right way to solve my problem: Why it's not returning the desired results?
For a simple one to many, just store the foreign key to distrito on the user model, no need for intermediate tables.
$table->increments('id')->unsigned();
$table->string('name');
$table->string('last_name');
$table->string('profile_picture')->default('default.jpg');
$table->string('userProfile')->default('');
$table->float('stars')->default(0);
$table->integer('distrito_id')->unsigned();
$table->foreign('distrito_id')->references('id')->on('distrito');
and get rid of the distrito_user table altogether. now use has this method:
public function distrito(){
return $this->belongsTo(Distrito::class, 'id');
}
while distrito has:
public function users(){
return $this->hasMany(User::class);
}
also change distrito migration to:
$table->increments('id')->unsigned();

Eloquent Relationships Not Working as Expected

I am trying to understand what I am missing here.
Apps migration
Schema::create('apps', function (Blueprint $table) {
$table->increments('id');
$table->integer('show_id')->unsigned()->index();
$table->string('name');
$table->integer('provider_id')->unsigned()->index();
$table->timestamps();
});
Show migration
Schema::create('shows', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
So I create an apps model that has the following function
public function Show() {
return $this->hasOne(Show::class);
}
But in php artisan tinker when I do $app->Show; I get the following error:
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1 no such column: shows.app_id (SQL: select * from "shows" where "shows"."app_id" = 1 and "shows"."app_id" is not null limit 1)'
Am I mis-understanding the relationships?
Your relation should be as:
Apps model:
public function show() {
return $this->hasOne(Show::class, 'id', 'show_id');
}
Or it can be:
public function show() {
return $this->belongsTo(Show::class);
}
Docs
You do not have an app_id in your shows migration.
edit: Taking from the Laravel Docs and changing it to fit your situation
Eloquent determines the foreign key of the relationship based on the model name. In this case, the show model is automatically assumed to have a app_id foreign key.
A one-to-one relationship consists of a hasOne and a belongsTo. The table that contains the foreign key field must be on the belongsTo side of the relationship.
Since your apps table contains the show_id field, it is stated that apps belong to shows, and shows has one (or many) apps.
Given this, you need to change your Show relationship on your Apps model to use the belongsTo relationship.
public function Show() {
return $this->belongsTo(Show::class, 'show_id');
}
Unless you rename your relationship method so that it is lowercase (function show()), the second parameter is required. If you renamed the relationship, Laravel could build the proper key name and you could leave off the second parameter:
public function show() {
// For belongsTo, second parameter defaults to {function_name}_id.
return $this->belongsTo(Show::class);
}
In your apps model :
public function Show() {
return $this->belongsTo('yourmodelnamespace\Show','id','show_id');
}
And you need create Show model too ..
Hope it will works~~
You can use relation like this
public function Show() {
return $this->hasOne(Show::class, 'id','id');
}

how to eager load in a Many to Many relationship in laravel 5?

My user table and item table are related by a many to many relationship, the item table has some data in foreign tables, example color table I have a pivot table that relates the two.
My question is, if I want to retrieve all the items associated to a user with a color how do I get them with eager loading?
I know that $user->item will retrieve all the items for that user.
But if I want to eager load all the items for that user with the color attributes in one query, how do I do it?
At the moment I am looping through the items associated to the user and lazy loading every data I need, for example
foreach($user->item as $i){
echo($i->item->color)
}
This means every cycle makes a new query...
here the models:
User model:
public function item(){
return $this->belongsToMany('App\item')->withTimestamps();
}
item model:
public function user(){
return $this->belongsToMany('App\User');
}
and this the schema for the pivot table
Schema::create('item_user', function(Blueprint $table) {
$table->unsignedInteger('user_id')->unsigned()->index();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->unsignedInteger('item_id')->unsigned()->index();
$table->foreign('item_id')
->references('id')
->on('items')
->onDelete('cascade');
$table->timestamps();
});
You can simply use a Nested Eager Loading
Eager loading is done using with(): in your instance you could use the following:
public function item(){
return $this->belongsToMany('App\item')->withTimestamps()->with('color');
}
This will eager load the color on the "item". However you can also eager load immediately on the User model in your controller:
User::with('items.color')->find(1);
I'm not sure based on your code that the relations/model is like this, but you get the point I guess.

Stuck at defining relationship in laravel 4

i'm trying to understand laravel by creating a messaging application. User should be able to send message to each other. i have made a similar application using core php.
I'm done with login/authentication and migration and now stuck at defining relationship in models;
i have created 3 tables using migrations:
users
conversations
conversations_reply
This is the Schema of:
users table (For storing detail of users)
$table->increments('id');
$table->string('username', 50);
$table->string('password', 50);
$table->string('name', 50);
$table->string('email', 254);
$table->timestamps();
conversations table(For storing conversation between users)
$table->increments('id');
$table->integer('user_one'); //foreign key of one friend from users table
$table->integer('user_two'); //foreign key of second friend from users table
$table->string('ip');
$table->timestamps();
conversations_reply table(For storing Conversation text)
$table->increments('id');
$table->text('reply');
$table->integer('user_id');
$table->integer('conversation_id'); //foreign key of conversations table
$table->string('ip');
$table->timestamps();
Now, i'm trying to define relationships in models as:
User model wil have hasMany relationship with both Conversation and ConversationReply model.
Conversation will have belongsToMany relationship with User model and hasMany relationship with ConversationReply model.
ConversationReply model will have belongsToMany relationship with both User and Conversation model.
Now i'm stuck at defining relationship in the first model(User)and unable to proceed further because i need to define local and foreign key, but i'm unable to do so because conversations table will have 2 foreign keys(of 2 users) and i can define only one foreign key.
Edit: There should be only two members in a conversation and and two users should have only one conversation(like facebook). Their new messages should be added to their old conversations. In conversations table, ip is the ip address of the user who would start the conversation and in the conversations_reply table, ip is the respective ip of the user
There seems to be a little flaw in your abstraction. You have actually designed user1 and user2 as attributes of the Conversation entity, but they are not attributes. Also, what is the IP of a conversation?
Attributes of a Conversation may be topic, start time, end time, amount of messages and things like that.
And then a conversation has members. Not exactly two but many. So you could just create an entity / model ConversationMembers that connects User and Conversation:
conversation_members table:
$table->increments('id');
$table->integer('conversation_id');
$table->integer('user_id');
$table->string('ip');
$table->string('nickname');
and change the conversations table accordingly:
$table->increments('id');
$table->boolean('public);
// other attributes you're interested in
$table->timestamps();
Now you can define the relationships on your models:
Conversation:
public function members()
{
return $this->hasMany('ConversationMember');
}
public function messages()
{
return $this->hasMany('ConversationReply');
}
ConversationMember:
public function user()
{
return $this->belongsTo('User');
}
public function conversation()
{
return $this->belongsTo('Conversation');
}
User:
public function conversations()
{
return $this->hasManyThrough('Conversation', 'ConversationMember');
}
public function replies()
{
return $this->hasMany('ConversationReply');
}
I hope this helps.

Resources