Add friend model to belongs to many relationship - php

Table friend:
$table->integer('user_id');
Table friend_user:
$table->integer('user_id');
$table->integer('friend_id');
$table->primary(['user_id', 'friend_id']);
User model:
public function friends()
{
return $this->belongsToMany(User::class, 'friend_user', 'user_id', 'friend_id');
}
UserController:
public function getAddFriend(User $user)
{
Auth::user()->friends()->attach($user->id);
return redirect()->back();
}
Why is it that if I write $user->id in attach(), the data is not inserted into table friend_user, but if I write the id(1, 2 or something else) in attach(), the data is inserted into the table friend_user?
How to add the data in the table friend_user after clicking?

I believe the underlying problem is model binding, i presume your route has a parameter called user. Then i would explicit define your model binding in AppServiceProvider.php or RouteServiceProvider.php boot() method.
use Illuminate\Support\Facades\Route;
Route::model('user', User::class);

Related

can't find questions by category name in Laravel

i am trying to retrieve questions based on the category witch they belong with this function inside my questions controller:
public function getByCategoryName($categoryName) {
$category = Category::where('name', $categoryName)->first();
return response($category->questions);
}
the problem is that, even if $category its being correctly set, $questions is null and the browsers returns an empty response to my request
the tables are created like this:
Questions table:
Schema::create('questions', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('title')->nullable(false);
$table->string('content')->nullable(false);
$table->integer('points')->default(0);
$table->foreignId('user_id')
->constrained('users')
->onDelete('cascade');
$table->string('category_name');
$table->foreign('category_name')
->references('name')->on('categories')
->onDelete('cascade')
->onUpdate(null);
});
categorie table:
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('name')->nullable(false);
$table->unique('name');
});
I have the relatives relationship functions HasMany and BelongsTo seated inside the the models.
Question model:
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
Category model:
public function question() : HasMany {
return $this->hasMany(Question::class);
}
What am I doing wrong?
As others have pointed out. It's better to use the primary ID key for efficient mapping. However, for education purposes it is possible and I will explain. Eloquent determines the foreign key name by examining the name of the relationship method and suffixing the method name with _id.
So, in this case, Eloquent assumes that the Question model has a category_id column.
However, since the foreign key on the Question model is not category_id, we must pass a custom key name as the second argument to the belongsTo method:
public function category()
{
return $this->belongsTo(Category::class, 'foreign_key'); // If we do not pass this eloquent thinks the foreign key is 'category_id'
}
// We need to pass our custom foreign key
public function category()
{
return $this->belongsTo(Category::class, 'category_name');
}
Eloquent assumes the parent model Category will be associated using its primary id. Since this is not our case we need to associate the parent model key to the 'name' column.
So we need to pass a third argument to the belongsTo method specifying the parent tables custom key:
public function category()
{
return $this->belongsTo(Category::class, 'category_name', 'name');
}
Your complete solution should look something like this.
// Question model
public function category()
{
return $this->belongsTo(Category::class, 'category_name', 'name');
}
// Category model
public function questions()
{
return $this->hasMany(Question::class, 'category_name', 'name');
}
Change this :
public function question() : HasMany {
return $this->hasMany(Question::class);
}
To this :
public function questions() : HasMany {
return $this->hasMany(Question::class, 'category_name');
}

Laravel: Query Many to Many Pivot table

I have an app where Users can have multiple Books. I have set up the relation ship and the intermediary table. But the query is not working.
Book Model
public function user(){
return $this->belongsToMany('App\Book', 'book_user');
}
User Model
public function book(){
return $this->belongsToMany('App\User', 'book_user');
}
Create user_book table migration:
public function up()
{
Schema::create('book_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('book_id')->unsigned();
$table->foreign('book_id')->references('id')->on('books');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
});
}
Books controller I add the book_id and user _id to the table
public function readlist(Book $book)
{
DB::table('book_user')->insert(
['user_id' => auth()->id(),
'book_id' => request('book_id')]
);
}
In my home controller I try to access the books related to a user but my results return Null;
public function index()
{
$user = Auth::user();
$userbooks =$user->books;
dd($userbooks);
return view('/home');
}
First rename you book() method to books() in your User model :)
Then you can try to do this:
public function readlist(Request $request)
{
Auth::user()
->books()
->attach($request->get('book_id'));
}
User have multiple Books,
Book have multiple Users,
The relationship is many to many,
It's better to define the User model:
public function users(){
return $this->belongsToMany('App\Book', 'book_user');
}
And in your Book model
public function books(){
return $this->belongsToMany('App\User', 'book_user');
}
The Doc Link: https://laravel.com/docs/5.7/eloquent-relationships#many-to-many

Laravel 5.1 Multiple Many to Many Relationship on the Same Model

I seen to of got tangled in Laravel's ORM with the following:
Scenerio: All Users have a Watchlist, the Watchlist contains other Users.
I can't seem the get the relationships to work correctly as they are cyclical, so far I have the following:
class UserWatchlist extends Model
{
protected $table = 'UserWatchlist';
public function Owner() {
return $this->belongsTo('App\User');
}
public function WatchedUsers() {
return $this->hasMany('App\User');
}
}
Schema::create('UserWatchlist', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('Users')->onDelete('cascade');
$table->integer('watched_id')->unsigned();
$table->foreign('watched_id')->references('id')->on('Users')->onDelete('cascade');
$table->timestamps();
});
class User extends Model
{
public function Watchlist() {
return $this->hasOne('App\UserWatchlist');
}
public function WatchedBy() {
return $this->belongsToMany('App\UserWatchlist');
}
}
It is not pulling through the correct in formation i'm expecting. Am I missing something fundamental?
Since UserWatchlist is a pivot table, i suppose you are facing a many to many relationship with both the elements of the relation being the same model (User)
If that is the case, you should not build a model for the pivot table UserWatchlist but all you have to do is to set the relation between the users through the pivot table:
class User extends Model
{
//get all the Users this user is watching
public function Watchlist()
{
return $this->belongsToMany('User', 'UserWatchlist', 'user_id', 'watched_id' );
}
//get all the Users this user is watched by
public function WatchedBy()
{
return $this->belongsToMany('User', 'UserWatchlist', 'watched_id', 'user_id' );
}
}
Check here for more info on many-to-many relationship

Laravel 5 Querying with relations causes "Call to a member function addEagerConstraints() on null" error

I have been trying to create a simple user management system but keep on hitting road blocks when it comes to querying relations. For example I have users and roles and whenever I try to make a query for all users and their roles I get an error. The one in the title is only the latest one I've encountered.
My User and Role Models look like this:
class Role extends Model
{
public function users()
{
$this->belongsToMany('\App\User', 'fk_role_user', 'role_id', 'user_id');
}
}
class User extends Model
{
public function roles()
{
$this->belongsToMany('\App\Role', 'fk_user_role', 'user_id', 'role_id');
}
}
My migration table for many-to-many relationship between the two looks like this:
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable(); //fk => users
$table->integer('role_id')->unsigned()->nullable(); //fk => roles
$table->foreign('fk_user_role')->references('id')->on('users')->onDelete('cascade');
$table->foreign('fk_role_user')->references('id')->on('roles')->onDelete('cascade');
});
}
And then I try to get all records with their relation in a controller:
public function index()
{
$users = User::with('roles')->get();
return $users;
}
So I need another pair of eyes to tell me what is it I am missing here?
You are missing return statements in the methods that define relations. They need to return relation definition.
Replace
public function roles()
{
$this->belongsToMany('\App\Role', 'fk_user_role', 'user_id', 'role_id');
}
With
public function roles()
{
return $this->belongsToMany('\App\Role', 'role_user', 'user_id', 'role_id');
}
You forgot the return in your functions
Do:
return $this->belongsToMany('\App\User', 'fk_role_user', 'role_id', 'user_id');
return $this->belongsToMany('\App\Role', 'fk_user_role', 'user_id', 'role_id');
You need to use Return for your function's result. If you do not do that, Laravel does not know What should do with that function without any action.
Just use like this
return $this->hasOne(xxx, xx, xx);
Enjoy your coding !
Make sure you have written return in your model function relation.
return $this->hasMany('App\StaffShift','user_id','user_id');

Laravel, Eloquent table relating to itself through pivot table

I have users class (table):
id
username
And relations table:
user_id
subscribed_by
Idea: each User can subscribe for each other user.
Last variant was (don't work):
/* class User extends Eloquent ... */
public function followers() {
return $this->belongsToMany('User', 'rel_table')->withPivot('user_id');
}
public function following() {
return $this->belongsToMany('User', 'rel_table')->withPivot('subscribed_by');
}
Need help: how to set up this?
First, an advice, you should rename the fields in your pivot table follower_id and followed_id (or something like that). That's more clear.
Then you have to define relations like that :
public function followers() {
return $this->belongsToMany('User', 'rel_table', 'followed_id', 'follower_id');
}
public function following() {
return $this->belongsToMany('User', 'rel_table', 'follower_id', 'followed_id');
}
The withPivot method is used to define other attributes on the relation than the two foreign keys.

Categories