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
Related
I'm trying to make a site where users have projects, and I'm trying to make a kind of "activity wall" to improve the communication of each project, so this "activity wall" messages belong to the project and the Messages inserted in it belong to the user too. So, I created the migration below:
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->string('content'); //the message
$table->string('file'); //if has a file
$table->integer('user_id')->constrained(); //to make the relationship with the Users table
$table->integer('projeto_id')->constrained();//to make the relationship with the Projetos (Projectc) table
$table->timestamps();
});
And in Projeto Model, I create the relation.
Projeto.php
public function message()
{
return $this->hasMany(Message::class);
}
The same to
User.php
public function messages()
{
return $this->hasMany(Message::class);
}
And this to
Message.php
public function projetos()
{
return $this->belongsTo(Projeto::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
But the problem is: When I try to get the Messages table with the Project relationship.
public function index($id)
{
$projeto = Projeto::findOrFail($id);
$messages = $projeto->message;
}
I can't get the User relationship to get the owner username of the message to return to my view. What is the better way to do this?
you should use with, to prevent n query:
public function index($id)
{
$projeto = Projeto::with('message', 'message.user') // this will get the relation `message`, and `user` from the message
->findOrFail($id);
$messages = $projeto->message;
}
I am making FollowController where I have two tables following_users table and following_user_item table. which is in hasMany relationship. When a authenticate current_user wants to follow an user, the ID of the user will stored in following_users table and its relational table stored the current_user_id and the following_user_id (which is the id of following_users table). here is the schema.
following_users_table:
public function up()
{
Schema::create('following_users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')
->references('id')
->on('users');
$table->timestamps();
});
}
following_user_item_table:
public function up()
{
Schema::create('following_user_items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('following_users_id')->unsigned();
$table->foreign('following_users_id')
->references('id')
->on('following_users');
$table->bigInteger('user_id')->unsigned();
$table->timestamps();
});
}
I have done the FollowController but the problem is comming when try to check whether the user is already followed or not.
Follow Relationship in User model
public function followingUserList()
{
return $this->hasOne('App\FollowingUser');
}
/**
* Get the stories associated with the user through an intermediate table
*
*/
public function followingUsers()
{
return $this->hasManyThrough(
'App\FollowingUserItem',
'App\FollowingUser',
null,
'following_users_id'
);
}
FollowingUser Model Relationship with User and FollowingUserItem
public function user()
{
return $this->belongsTo('App\User');
}
public function users()
{
return $this->hasMany('App\FollowingUserItem','following_users_id');
}
Here is my FollowController:
class FollowController extends Controller
{
//
public function index($id)
{
$user = User::find($id);
$logged_userId = Auth::User();
if ($user->id == $logged_userId->id) {
return [
'status' => false,
'message' => 'You can not Follow yourself',
];
}
if ($user && $logged_userId) {
$checkUsers = FollowingUser::where('user_id', $user->id)->get()->users()->where('user_id', $logged_userId->id);
if ($checkUsers)
{
return 'already followed';
}
else
{
$user->followingUserList()->save(new FollowingUser())->users()->save(new FollowingUserItem(['user_id' => $logged_userId->id]));
return 'sucess';
}
}
}
}
I go the error
Method Illuminate\Database\Eloquent\Collection::users does not exist.
When you call get() Laravel returns a collection as it does not know how many rows there will be there. This is why you get collection does not have users set error. Since you filter on an id you know there is only gonna be one, therefor you can utilize the first() method.
So change the code to use first().
$checkUsers = FollowingUser::where('user_id', $user->id)->first()->users()->where('user_id', $logged_userId->id);
I wanted to implement a follow system where a User can follow Comment, Category, Post and more. I have tried using Laravel Polymorphic relations for this but could not wrap my head around it. If someone can guide me it will be great.
Here is what I have tried.
User Model
public function categories()
{
return $this->morphedByMany(Category::class, 'followable', 'follows')->withTimestamps();
}
Category Model
public function followers()
{
return $this->morphMany(Follow::class, 'followable');
}
Follow Model
public function followable()
{
return $this->morphTo();
}
public function user()
{
return $this->belongsTo(User::class);
}
Follow migration
Schema::create('follows', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->morphs('followable');
$table->timestamps();
});
How can I get the all the categories, comments followed by a user. Also how I can get the Followers of a Cateogry or Commnets etc.
Please help.
You dont't need Follow model.
All you need is pivot table like so
followable
user_id - integer
followable_id - integer
followable_type - string
add folowers method to all your classes which you need to follow
For example
Category Model
public function followers()
{
return $this->morphToMany(User::class, 'followable');
}
Then in User Model
public function followers()
{
return $this->morphToMany(User::class, 'followable');
}
public function followedCategories()
{
return $this->morphedByMany(Category::class, 'followable')->withTimestamps();
}
public function followedComments()
{
return $this->morphedByMany(Comment::class, 'followable')->withTimestamps();
}
public function followedPosts()
{
return $this->morphedByMany(Post::class, 'followable')->withTimestamps();
}
// and etc
public function followedStuff()
{
return $this->followedCategories
->merge($this->followedComments)
->merge($this->followedPosts);
}
Then you can reach your goal by accessing to followers of certain category, comment or post or whatever you wish(if it followable of courcse)
For example:
$folowers = $category->folowers;
// will return all followers this category
$all = $user->followedStuff();
// will return collection of all things followable by the user
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
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');