I'm currently working on a quiz application in laravel 5.6 and am attempting to fetch all quizzes that belong to the current authenticated user.
I have three tables:
users
quizzes
user_quizzes
The quizzes table simply holds all the information relating to the quiz such as:
- id
- quiz_name
- quiz_description
- active
- total_plays
- created_at
- updated_at
The users table is just the laravel default with minor changes:
- id
- username
- email
- password
- remember_token
- created_at
- updated_at
The user_quizzes table holds two fields (both foreign keys): user_id and quiz_id.
At the moment it outputs ALL the quizzes, rather than just ones belonging to the current user.
In my QuizController I have:
$quizzes = Quiz::find(Auth::user()->id)->with('user')->get();
And my QuizModel:
class Quiz extends Model
{
protected $table = 'quizzes';
public function user()
{
return $this->belongsTo('App\Models\User');
}
}
Finally the UserModel contains:
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'username', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function activation()
{
return $this->hasOne('App\Models\Activation');
}
public function profile()
{
return $this->hasOne('App\Models\Profile');
}
public function quizzes()
{
return $this->hasMany('App\Models\Quiz');
}
}
I have also tried using the DB facade with joins but received the same output (all quizzes returned, not just ones belonging to the current user). Here is what I did for that, just for reference:
$quizzes = DB::table('user_quizzes')
->join('users', 'users.id', '=', 'user_quizzes.user_id')
->join('quizzes', 'quizzes.id', '=', 'user_quizzes.quiz_id')
->get();
I feel like I am making a silly mistake, so any guidance would be greatly appreciated.
You need to change Eloquent relationship in the Model.
class User extends Model {
public function quizzes()
{
return $this->belongsToMany(Quiz::class, 'user_quizzes','user_id', 'quiz_id');
}
}
Same with Quiz Model
class Quiz extends Model
{
protected $table = 'quizzes';
public function user()
{
return $this->belongsToMany(User::class, 'user_quizzes','quiz_id', 'user_id');
}
}
DB facade you're doing incorrectly.
You want to fetch all quizzes for the users so you need to query quizzes table like this.
DB::table('quizzes')->leftJoin('user_quizzes', 'user_quizzes.quiz_id', 'quizzes.id')->join('users', 'user_quizzes.user_id', 'user_id')->where('users.id', $USER_ID)->get();
Related
I have three table which is explained below
User
id
email
password
specialities
id
name
active
results
id
specialitie_id
user_id
result
color
i am trying to relate results with the rest of the 2 tables, but i don't know how to do it, below is my model relation, please correct me if there's any issue, i can't fetch the data due to having wrong relation
Result Model
class Result extends Model
{
use HasFactory;
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function speciality()
{
return $this->belongsTo(Speciality::class);
}
}
User Model
class User extends Authenticatable implements MustVerifyEmail
{
public function result()
{
return $this->hasMany(Result::class);
}
}
i am trying to expect a correct result of my relation database tables in laravel
Since the results table is Intermediate Table Columns.use laravel belongsToMany method so no need to create results model.Treat results table as pivot table.
In User Model add relation like below
public function specialities()
{
return $this->belongsToMany(Speciality::class,'results')->withPivot('result','color');
}
Also read here Many To Many Relationships
I've got table structure like this:
users:
id
name
managers:
id
user_id
user_manager:
manager_id
user_id
vacations:
user_id
date_from...
My task is to fetch all data from vacations table where user (vacations.user_id) belongs to given manager id (managers.user_id) and that assigment is in pivot table user_manager. User can have many managers, manager can have many users. I've been trying to do this, but I've got stuck. My workaround was this:
DB::table("vacations")
->leftJoin("users", function ($join) {
$join->on("vacations.user_id", "=", "users.id");
})
->leftJoin("user_manager", function ($join) {
$join->on("user_manager.user_id", "=", "users.id");
})
->where("user_manager.manager_id", "=", $id)
->get();
But I want to know a way to make this with eloquent model and all of it's fancy stuff.
Manager model:
class Manager extends Model
{
use HasFactory;
protected $table = 'managers';
protected $fillable = ['user_id'];
public function users()
{
return $this->belongsToMany(User::class, 'employee_manager')->withTimestamps();
}
}
User model:
class User extends Model
{
use HasFactory, Notifiable;
public function managers()
{
return $this->belongsToMany(Manager::class, 'employee_manager')->withTimestamps();
}
}
You are trying to get all Vacation records which created by a User which belongs to a specific Manager
It means you need to get all Vacations where user_id in that Manager
's users()
You can achieve this with a basic way like this;
$vacationsThatConcernTheManager = Vacation::whereIn('user_id', $manager->users()->pluck('id'))->get();
And if you want use directly something like $manager->vacations() you can use hasManyThrough as described in documentation.
Add this relation to your Manager model;
public function vacations()
{
return $this->hasManyThrough(Vacation::class, User::class);
}
Hey from my website I'm sending multiple notifications to users, I'm assigning users to a team and then I assign this team to the notifications table.
However when I do SiteNotification::find(1)->notifications() then I get the name of the team, however, I was looking to get the user model and all the details related to that. Is there an easy way to obtain this using Laravel Eloquent relationships?
My DB model and Eloquent model are below;
DB tables;
User
id | username | email
Teams
id | name |
Team Members
team_id | user_id
Site Notifications
site_notification_id | team_id
Model Here:
class SiteNotification extends Model {
public function notifications()
{
return $this->belongsToMany(Team::class, 'site_check_notifications', 'site_check_id', 'team_id');
}
}
Update:
I've tried updating the Team Model as follows;
class Team extends Model
{
public function users()
{
return $this->hasManyThrough(
User::class,
TeamMember::class,
'team_id',
'id'
);
}
}
However this throws an error as follows when running this;
$site = Site::find(1);
foreach( $site->notifications as $notification) {
dd($notification->users);
}
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'team_members.id' in 'on clause' (SQL: select `users`.*, `team_members`.`team_id` from `users` inner join `team_members` on `team_members`.`id` = `users`.`id` where `team_members`.`team_id` = 4)
Any ideas what I'm doing wrong??
I've found a solution which has meant that I do not need to amend my existing database structure and I've found the correct relationship to use.
public function users()
{
return $this->belongsToMany(
User::class,
'team_members',
'team_id',
'user_id'
);
}
Now I can do Site::find(1)->users->pluck('email')
You have to change the model structure... This is how I would have reached your goal... Take it as a "working solution", maybe not the best!
First of all, database. You should have these tables, there is no need to
users => users table
teams => teams table
team_user => pivot table n:n
team_site_notification => pivot table n:n
site_notifications => notifications table
user_site_notification => pivot table n:n
Then you create the related models relations
public class User {
// [...]
public function teams() {
return $this->belongsToMany(Team::class)
}
public function notifications() {
return $this->belongsToMany(SiteNotification::class)
}
}
public class Team {
// [...]
public function users() {
return $this->belongsToMany(User::class)
}
public function notifications() {
return $this->belongsToMany(SiteNotification::class)
}
}
public class SiteNotification {
// [...]
public function teams() {
return $this->belongsToMany(Team::class)
}
public function users() {
return $this->belongsToMany(User::class)
}
}
In your controller, when you create the SiteNotification model, you'll have to associate also the users. For example
public function store(Request $request) {
// Do your stuff
$team = Team::findOrFail($request->your_team_id);
$notification = Notification::create($data);
$notification->teams()->associate($request->your_team_id);
// Retrieve the users from the team... Maybe not everyone should receive a notification
$team->users()->whereIn('id', $user_ids)->get()->pluck('id')
$notification->users()->associate($ids);
}
When you want to get your users list you simple retrive the associated users in this way:
dd($notification->users);
// [ User:{id: 1, '...'}, User:{id: 2}, User:{id: 7} ]
Hope this is what you're looking for!
Been learning laravel for 4 days and im trying to fix this error for 2 hours and i cant still fix it. I can save on one to many relationship but i cant retrieve data i think there something wrong with the relationship. Im trying to retrieve posts on user using this line but im getting not empty results on users but empty result on posts. Same thing happening on categories and posts which is many to many relationship but i cant save on many to many.
$users = User::with('posts')->get();
ANd im getting an error when i use this the error is
Undefined property: Illuminate\Database\Eloquent\Collection::posts()
$users = User::where('user_id','=','2')->get();
$posts = $users->posts()->get();
Heres my user Model
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $primarykey = 'user_id';
protected $table = 'users';
public function posts(){
return $this->hasMany("App\Post");
}
}
Heres my posts Model
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $primarykey = 'id';
protected $table = 'posts';
public function post_validation_rules(){
return [
'post_title' => 'required|min:5|unique:posts',
'post_body' => 'required'
];
}
public function user(){
return $this->belongsTo("App\User");
}
public function categories(){
return $this->belongsToMany('App\Category', 'category_id', 'category_id');
}
}
Categories Post
class Category extends Model
{
protected $primarykey = 'category_id';
protected $table = 'categories';
public function posts(){
return $this->belongsToMany('App\Post', 'post_id', 'id');
}
}
Database
Posts Table
id
user_id
post_title
post_body
createad_date
updated_date
Users Table
user_id
username
email
pass
createad_date
updated_date
You can only call relations on a single object, not on an entire collection. $users is a collection of User objects.
If you want a single user object, use the first() function to get the first User object that matches.
$user = User::where('user_id','=','2')->first();
$posts = $user->posts;
Update:
To get the posts directly in the user object, you need to use the with function:
$user = User::with('posts')->where('user_id','=','2')->first();
Try to declare the field that have the relation between your tables then, for example:
$this->hasMany(App\Post::class, 'user_id', 'user_id');
Laravel is searching for a field id in User table but it does not exist. so with this way you will tell it that the field you look is user_id
I've got Tag and Attendee Eloquent models, they are in many-to-many relation. Pivot table has also two more attributes – value_int and value_string. My Attendee model looks like this:
class Attendee extends Model
{
public $timestamps = false;
protected $fillable = [
'event_id'
];
public function tags() {
return $this->belongsToMany('App\Models\Tag', 'attendee_tag', 'attendee_id', 'tag_id')
->withPivot(['value_string', 'value_int']);
}
public function scoreTagValue($tag_id) {
return $this->tags->where('tag_id', '=', $tag_id)->first();
}
}
What I want is to obtain pivot values based on Attendee model and variable tag_id, so I've written scoreTagValue function, but it always returns null and I don't know why :( I'm calling it this way:
$attendee->scoreTagValue($tag_id). Thanks for your help :)
You need to access the relation, not the property:
public function scoreTagValue($tag_id) {
return $this->tags()->where('tag_id', '=', $tag_id)->first();
}
Also, according to the docs, withPivot() does not take an array, so:
->withPivot('value_string', 'value_int');