Laravel Pivot Table and indirect relationship - php

I'm writing a survey with Laravel 4 and need the ability for users to be able to take the same survey multiple times (and have their answers saved as different instances.)
I currently have a pivot table called survey_user that links a user to an invited survey. A potentially positive side effect of the pivot table is that its primary key could be used to have unique survey instances.
My problem is figuring out how to get answers, specifically through the user model. Answers table would contain a foreign key to the primary of the pivot table.
My User model:
class User extends Eloquent {
public function surveys() {
return $this->belongsToMany('Survey', 'survey_user')
->withPivot('id', 'completed_at');
}
public function answers() {
// This should return all of the user's answers, irrespective of
// survey id's.
}
}
Tables:
surveys: id
users: id
survey_user: id, survey_id, user_id, completed_at
answers: survey_user_id, answer_text, ...
How might I accomplish this psuedo-relationship or perhaps a better way to structure?

Use relationships! Here's how I would do it:
class User extends Eloquent {
public function surveys() {
return $this->belongsToMany('Survey');
}
public function answers() {
return $this->hasMany('Answer');
}
}
class Survey extends Eloquent {
public function surveys() {
return $this->belongsToMany('User');
}
public function answers() {
return $this->hasMany('Answer');
}
}
class Answer extends Eloquent {
public function survey() {
return $this->belongsTo('Survey');
}
public function user() {
return $this->belongsTo('User');
}
}

Related

Loading values from many-to-many realtionship plus values from auto-generated table in Laravel

I am working on some kind of ambulance app and I need help on how to load relationship.
So, I have table appointment_statuses (and it is populated over the seeder because I need only 3 states - Done, In Progress, Not Performed), I have also the many-to-many relationship between the User model and Appointment model (appointment_user table which holds only IDs of both models) and now I am working on EMR system which means I can check all appointments that patient had in history.
Here is the image of the issue
So under "Status" I want to load name of that ID from appointment_statuses table instead to have only ID.
These tables have this structure:
Appointments
Status
These tables have these values:
Appointments table
Appointment statuses table
These are relations:
User:
public function role()
{
return $this->belongsTo(Role::class);
}
public function patient()
{
return $this->hasOne(Patient::class);
}
public function appointments()
{
return $this->belongsToMany(Appointment::class);
}
Appointment:
public function users()
{
return $this->belongsToMany(User::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
public function appointmentStatus()
{
return $this->belongsTo(AppointmentStatus::class);
}
Appointment_Statuses:
public function patient()
{
return $this->belongsTo(Patient::class);
}
public function appointment()
{
return $this->belongsTo(Appointment::class);
}
Here is a controller which is responsible for emr:
After I have added to controller this:
$user = User::with(['appointments', 'appointments.appointmentStatus'])->where('id', $id)->firstOrFail();
I get this in frontend:
{{ dd($user->toArray()) }}
SOLUTION TO THIS ISSUE
For anyone in future who gets this kind of issue just check the convention about the naming of the foreign keys. In my example, it was the issue, and if you are not sure that your foreign key name is correct then just in the model provide more information like this:
public function appointmentStatus()
{
return $this->belongsTo(AppointmentStatus::class,'appointment_statuses_id','id');
}
You can use nested relationship
$user=User::with(['appointments','appointments.appointmentStatus'])
->where('id',$id)
->first();
Also you have to modify relationship
public function appointmentStatus()
{
return $this->belongsTo(AppointmentStatus::class,'appointment_statuses_id','id');
}
For anyone in future who gets this kind of issue just check the convention about the naming of the foreign keys. In my example, it was the issue, and if you are not sure that your foreign key name is correct then just in the model provide more information like this:
public function appointmentStatus()
{
return $this->belongsTo(AppointmentStatus::class,'appointment_statuses_id','id');
}

Laravel whereDoesntHave union whereHas

I'm trying to query my models that don't have relation and union it with the ones that have relations but I get an error with memory being exhausted.
Post::whereDoesntHave('comments')
->union(Post::newQuery()->whereHas('comments')->getQuery())
->paginate();`
Anyone know a better way of using the union?
Update Your Post Model with below code.
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class); //Pass Foreign Key if other than id
}
}
Update Your Comment Model with this code.
class Comment extends Model
{
public function post()
{
return $this->belongsTo(Post::class);//Pass Foreign Key if other than id
}
public function user()
{
return $this->belongsTo(User::class);//Pass Foreign Key if other than id
}
public function scopeNoComment($query)
{
return $query->count() == 0;
}
}
$comments = $post->NoComment()->with('user')->paginate(10);
Making a relationship would be easy to access data.

Laravel Eloquent elation for pivot table

I'm currently working on a laravel project, but I'm kind of stuck finding the right eloquent relations.
My tables and the connections (should) look like this:
Project Relations
My model relations look like this:
User
public function team()
{
return $this->hasMany(Team::class, 'user_id');
}
public function evaluation()
{
return $this->hasMany(Evaluation::class, 'user_id');
}
Team
public function user()
{
return $this->belongsTo(User::class);
}
public function survey()
{
return $this->hasMany(Survey::class, 'team_id');
}
Evaluation
public function user()
{
return $this->belongsTo(User::class);
}
public function survey()
{
return $this->hasMany(Survey::class, 'evaluation_id');
}
Survey
public function team()
{
return $this->belongsTo(Team::class);
}
public function evaluation()
{
return $this->belongsTo(Evaluation::class);
}
public function surveyresponse()
{
return $this->hasMany(SurveyResponse::class, 'survey_id');
}
SurveyResponse
public function survey()
{
return $this->belongsTo(Survey::class);
}
public function testquestion()
{
return $this->belongsTo('App\TestQuestion');
}
Is this the way to go? Do I need a "Has Many Through" relation here? Or a "Polymorphic Relationship"?
Seems correct to me, i just didnt see the TesteQuestion model (your last relation).
Answering your question:
The HasManyThrough relation is just a shortcut for accessing distant relations via an intermediate relation, in your case: Users has many evaluations that has many surveys. With this relationship you could get all surveys from a user.
Your relation would look like this:
/**
* Get all of the surveys for the user.
*/
public function surveys()
{
return $this->hasManyThrough('App\Survey', 'App\Evaluation');
}
You can access this relation like this:
$user->surveys();
But you can achieve the same (without using the HasManyThrough) by doing:
$user->evaluations()->surveys();
Beware that this will return the evaluations too, not just the surveys and it requires more processing.
So i recommend you doing the HasManyThrough relationship if you pretend to access the surveys a lot.

Laravel defining relationship

Am still new to laravel
I have the following tables
user
id
first_name
last_name
educations
id,
user_id //references user id
type
Now in my user model i would like to get a specific users educations which can be many
so a user can have many educations but each education belongs to a single user.
So in my user model i have
public function education()
{
return $this->hasMany('App\ApplicantEducation','id','user_id');
}
In my Education model i have
public function user()
{
return $this->belongsTo('App\User','user_id','id');
}
But the above fails, I cannot retrieve user specific educations
Where am i going wrong?
try this:
in User Model:
public function educations()
{
return $this->hasMany('App\ApplicantEducation', 'user_id');
}
in Education Model:
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
Change return $this->hasMany('App\ApplicantEducation','id','user_id');
to return $this->hasMany('App\ApplicantEducation','user_id', 'id'); you also ommit the id and user_id.
As your foreign_key is well formed, you can also rwite this simple code,
class User{
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}
}
Class Educations{
public function user()
{
return $this->belongsTo('App\User');
}
}
Here,
$this->hasMany('App\ApplicantEducation','id','user_id');
In above statement first argument should be Model second should be foreign key and the third one is any other key from Education model.
Here, second and third arguments are not mandatory.
In User Model
class User...{
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}
In Education Model
public function user()
{
return $this->belongsTo('App\User');
}
Here, additional parameters are not mandatory might be your addition parameters creates issue,
and now you can retrieve your user with Education by
$user = User::with('education')->get();
This can retrieve all the users with their education.
I hope it helps,Thank you, Happy coding.
You should try this:
Education Model
public function user()
{
return $this->belongsTo('App\User','user_id);
}
User Model
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}

`Trying to get property of non-object` using `hasManyThrough` relationship laravel 5

I am trying to develop a blog using Laravel 5 in which i have to show comment along with user on post.
Here is my database table schema.
User
id
name
Posts
id
post_content
user_id
Comments
id
comment
user_id
post_id
Here is my User Model
public function posts()
{
return $this->hasMany('App\Models\Posts');
}
public function comments(){
return $this->hasManyThrough('App\Models\Comments','App\Models\Posts');
}
Here is my Posts Model
public function user()
{
return $this->belongsTo('App\Models\User');
}
public function comments(){
return $this->hasMany('Ap\Models\Comments');
}
Here is my Comment Model
public function posts()
{
return $this->belongsTo('App\Models\Posts');
}
public function user(){
return $this->posts->name;
}
Here is my code how i am accessing user name
$comments = Comments::find(1);
$comment['comment'] = $comments->comment;
$comment['user_name'] = $comments->name;
$comment['post_id'] = $comments->posts->id;
may be i am not getting in right direction? if i am doing right then why it is not working.
In laravel 5 you do not call the model as you are doing. since the models are stored in the app folder just call like. Plus I think you need to define the relationship
class User extends Model {
public function phone()
{
return $this->hasOne('App\Phone');
}
}
class Phone extends Model {
public function user()
{
return $this->belongsTo('App\User');
}
}
$phone = Phone::find(1);
For the case of foreign keys and more regarding the Eloquent relationships in laravel 5 just follow the documentation on the laravel website. Make sure to look at dynamic properties of that are allowed by eloquent
http://laravel.com/docs/5.0/eloquent

Categories