Laravel defining a many-to-many relationship with the same table - laravel

So I have a posts table with a corresponding Post model. I want to have related posts for every post. Since a post can have many other related posts, it is a many-to-many relationship between the posts table and the posts table (same table).
So I created a related_posts pivot table with its corresponding model RelatedPost. I want to define this relationship in the two models. Like so:
Post model:
public function related()
{
return $this->belongsToMany(RelatedPost::class, 'related_posts', 'related_id', 'post_id');
}
RelatedPost model:
public function posts()
{
return $this->belongsToMany(Post::class, 'related_posts', 'post_id', 'related_id');
}
Now in my post controller after selecting a particular post, I want to get all its related posts. So I do this:
$post->related()->get();
But when I do this I get the following error message:
"SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'related_posts' (SQL: select related_posts.*, related_posts.related_id as pivot_related_id, related_posts.post_id as pivot_post_id from related_posts inner join related_posts on related_posts.id = related_posts.post_id where related_posts.related_id = 1) "
This is my migration for the pivot table:
Schema::create('related_posts', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('post_id');
$table->unsignedInteger('related_id');
$table->timestamps();
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->foreign('related_id')->references('id')->('posts')->onDelete('cascade');
});
I have searched all over everywhere and though the solutions I've found really make sense I haven't been able to get any of them to work.
Any help will be very much appreciated!

Thanks to #d3jn's comment on my question I was able to solve my problem. So I am posting the solution here just in case someone else might need it.
I am relating the Post model to itself not to the pivot model RelatedPost. So I don't need a RelatedPost model. I only need a pivot table (related_post), and the relation's ids namely related_id and post_id.
So with my migration unchanged, I only need to do away with the RelatedPost model and change my related() method in the Post model to look like this:
public function related()
{
return $this->belongsToMany(Post::class, 'related_posts', 'post_id', 'related_id');
}
And now everything works.

Related

Laravel belongs to Many relations

I can't speak English well. I'm Sorry.
There are 3 tables : adverts, advert_categories, categories.
I want to pull data, I get an error
Adverts::with(['categories'])->where("user_id", Auth::user()->id)->get();
public function categories(){
return $this->belongsToMany(AdvertCategories::class, 'advert_categories', 'advert_id', 'category_id');
}
advert_categories :
categories:
The first parameter of belongsToMany method should be your target table not the pivot table in your case is Category,
I suppose that your models are: Advert belongsToMany Category, and your pivot table is: advert_categories the you relationship definition should look like this:
public function categories(){
return $this->belongsToMany(Category::class, 'advert_categories', 'advert_id', 'category_id');
}
Laravel docs link

add relationship to added values in pivot table laravel

I'm new to laravel relationships, but i'm familiar with SQL. I'm trying to add a pivot table with other values than just the two main ids.
I have some users, and some teams. Each user can play multiple instruments, and can be in multiple teams, but they can only play one instrument per team.
My pivot migration:
Schema::create('team_members', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->integer('team_id')->unsigned();
$table->integer('instrument_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('team_id')->references('id')->on('teams')->onDelete('cascade');
$table->foreign('instrument_id')->references('id')->on('user_instruments')->onDelete('cascade');
});
I can already see this:
$team = Team::first();
$team->members->first()->details->instrument_id; // "2"
How can I define the relationship between instrument_id on user_instruments, so I can do $team->members->first()->details->instrument
UPDATE:
I found this one: https://medium.com/#DarkGhostHunter/laravel-has-many-through-pivot-elegantly-958dd096db
Not sure if it will work...
You should create an intermediate model TeamMember, in which you will define a relationship to Instrument. To achieve that, modify your many-to-many relationship on both Team and User, adding the option "using", like this:
// Team.php
public function members() {
return $this->belongsToMany(App\User::class, 'team_members', 'user_id')
->using(App\TeamMember:class);
}
Then you need to create a model for your pivot table called TeamMember, which will extend the class Pivot and define the relationship with Instrument.
class TeamMember extends Pivot {
public function instrument() {
return $this->belongsTo(App\Instrument::class);
}
}
Then you should be able to get the instrument like this (assuming you set a custom name for your pivot table as "details"): $team->members->first()->details->instrument.

Updating a Laravel pivot table when the pivot has a unique field

I have two models, User and Service, with a ManyToMany relationship. The pivot table has two additional fields, id_code and alias. There may be many relationships between User and Service, but each one is uniquely identified by the field id_code. I need to retrieve a specific record in the pivot table by the id_code, and update the alias for that record only.
My models:
User:
class User extends Authenticatable
{
//All attributes & other functions here...
public function linked_services(){
return $this->belongsToMany(Service::class)
->withPivot('alias', 'id_code')
->withTimestamps();
}
}
Service:
class Service extends Model
{
//All attributes & other functions here...
public function linked_users(){
return $this->belongsToMany(User::class)
->withPivot('alias', 'id_code')
->withTimestamps();
}
}
Service-User migration:
Schema::create('service_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id')->nullable();
$table->unsignedBigInteger('service_id');
$table->string('alias', 50)->nullable();
$table->string('id_code', 50);
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('service_id')->references('id')->on('services');
$table->timestamps();
});
In the update function, I get the specific $id_code from a view, but I don't know how to update the "alias" for that specific "id_code".
What I already tried and is not working:
public function update(Request $request, String $id_code){
foreach(Auth::user()->linked_services as $service){
if($service->pivot->id_code === $id_code){
$service->pivot->alias = $request->alias;
$service->pivot->save();
}
}
return redirect()->route('services_user.index');
}
This function updates ALL the existing pivot records for the service_user, I need to update only the specific record for an given "id_code".
I solved it!!! I tell you how:
Auth::user()->linked_services()
->wherePivot('id_code', $id_code)
->update(['alias' => $request->alias]);
I learned that $user->linked_services() (unlike $user->linked_services) returns a relationship object (in this case, belongsToMany), which contains all the relationship data (intermediate table, pivots, FKs, parent / related objects, etc), and the desired pivot can be accessed on that object with ->wherePivot().

Delete all records from related tables using laravel eloquent

I have 3 tables.
Posts
Likes
Post_images.
// Model Relations.
Posts hasMany likes.
Likes belongs to Posts.
post hasMany PostImages
post_imags belongs to Posts.
Now when i delete a post record i want to delete its related records from likes table as well as from post_images table,Besides this images should also be removed from storage.
How can i accomplish this ? any guidance would be highly appreciated.
If I understand correctly your query should be like this. But you cannot remove images with eloquent relations. So you need to do something like
$courses = \App\Course::all();
foreach($courses $ $course){
Storage::delete($course->image_column_name);
}
\App\Courses::with('sessions')->with('lessons')->delete();
I can give you better answer if you can share your models function, database schema and Storage information like where you store course images...
DB::table('users')->delete();
All users are deleted from 'user' Table
if you set table names with Models::table('abilities') in
Schema::create(Models::table('abilities'), function (Blueprint $table) {
$table->bigIncrements('id');
// other fields
}
you can use
DB::table(Models::table('abilities'))->delete();
as documented here you can
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
Models::table('abilities');
}

Laravel morphMany lists error (Call to a member function addEagerConstraints() on a non-object)

I have a problem with using morphMany relations in combination with lists in my model.
I do have a Meta model (morphMany) and a Resort model. The Resort model has a method metas() that just does this:
return $this->morphMany('Meta', 'metable');
public function metas()
{
return $this->morphMany('Meta', 'metable')->lists('value', 'key');
}
Now what I want to have is a key/value list, just like I am able to do with hasMany:
return $this->morphMany('Meta', 'metable')->lists('value', 'key');
But this doesn't work. If I use the same with hasMany on a different table, it works fine, so I assume there must be a difference between hasMany and morphMany in terms of the object structure.
The error I get is:
Call to a member function addEagerConstraints() on a non-object [/­vendor/­laravel/­framework/­src/­Illuminate/­Database/­Eloquent/­Builder.php, Line 471] (Laravel 4.2.8)
Table structure:
Schema::create('meta', function(Blueprint $table) {
$table->increments('id');
$table->integer('metable_id')->unsigned();
$table->string('metable_type', 255);
$table->string('key', 128);
$table->text('value');
$table->index('metable_id');
$table->index('key');
});
I hope any of you can help me with this issue.
Thanks a lot in advance.

Resources