Laravel how to get User Profile field from separate table - php

I am new to Laravel and Eloquent is quite a challenge for me to understand. I have a User and a UserProfile model and table. UserProfile table has user_id (FK to user's id), 'key, and value fields.
I want to get the values of all the UserProfile fields associated with the user_id. Here is my code but nothing works. I am sure I am making some stupid mistakes but still learning :) Laravel.
UserProfile Model
class UserProfile extends Model
{
public $timestamps = FALSE;
protected $fillable = [
'user_id',
'key',
'value',
];
public function user()
{
return $this->belongsTo(User::class);
}
}
User Model method
public function profileFields(){
return $this->hasMany(UserProfile::class);
}
UserProfile Migration
public function up()
{
Schema::create('user_profiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned();
$table->string('key', 191);
$table->longText('value');
$table->foreign('user_id', 'user_profile_uid_fk')
->references('id')
->on('users')
->onDelete('cascade');
$table->unique(['user_id', 'key'], 'user_profile_unique_key');
});
}
I am trying to get the profile fields for the user using User::findOrFail(10)->profileFields but it is giving me property not defined exception.
Need Help: Can anyone help me to make it work so I can get all user_profiles
fields from the profile table?
Error Output (Tinker)
>>> User::findOrFail(10)->profileFields
Illuminate/Database/QueryException with message 'SQLSTATE[42S02]: Base
table or view not found: 1146 Table 'velvetpaper.user_user_profile'
doesn't exist (SQL: select user_profiles.*,
user_user_profile.user_id as pivot_user_id,
user_user_profile.user_profile_id as pivot_user_profile_id from
user_profiles inner join user_user_profile on user_profiles.id
= user_user_profile.user_profile_id where user_user_profile.user_id = 10)'

The relation between users and user_profiles is a one to many.
You might have not restarted Tinker since you are getting the wrong error, dont forget to exit Tinker after the modification in the code. Once tinker is started, code changes wont affect it.

you can use join to implement this stuff. like this...
this is query builder
$data['profile']=DB::table(usertable)
->where('usertable.id',$id)
->leftjoin('userprofiletable','usertable.id','=','userprofiletable.user_id')
->first();
return view('profile_view',$data)
//view
$profile->fullname
$profile->sex
$profile->phone
...

Related

Many-to-many in same model

I need to use a many-to-many relationship to one model. I have an Article model, and I want to make a function so that other articles, typically recommended, can be attached to one article.
This is the function, it should work correctly.
$article = Article::where('id', $request->article_id)->first();
$articles_ids = json_decode($request->articles_ids);
$article->articles()->attach($articles_ids);
I have a question about how to create a table of relations in the database and in the model correctly, I did it like this, but even the migration does not work for me
Model
public function articles()
{
return $this->belongsToMany('App\Models\Article');
}
public function article_recommended()
{
return $this->belongsToMany('App\Models\Article');
}
db
Schema::create('article_article_recommended', function (Blueprint $table) {
$table->unsignedBigInteger('article_recommended_id')->nullable();
$table->foreign('article_recommended_id')
->references('id')->on('article_recommended')->onDelete('set null');
$table->unsignedBigInteger('article_id')->nullable();
$table->foreign('article_id')
->references('id')->on('articles')->onDelete('cascade');
});
error in migration
SQLSTATE[HY000]: General error: 1824 Failed to open the referenced table
'article_recommended' (SQL: alter table `article_article_recommended` add constraint
`article_article_recommended_article_recommended_id_foreign` foreign key
(`article_recommended_id`) references `article_recommended` (`id`) on delete set null)
What are you trying to do should be fairly simple , it's like a following system where each user is related to many users ( same model ) but also same table !
you are here trying to create another table which i consider unnecessary , you only need two tables
articles & recommendations
and the recommendation tabel will act as a pivot table for articles with its self thus creating a many to many relationship with the same table .
Article.php
public function recommendations() {
return $this->belongsToMany(Article::class , 'recommendations' , 'article_id' , 'recommended_article_id');
}
create_recommendations_table.php
Schema::create('recommendations', function (Blueprint $table) {
$table->primary(['article_id','recommended_article_id']);
$table->foreignId('article_id');
$table->foreignId('recommended_article_id');
$table->timestamps();
$table->foreign('article_id')->references('id')->on('article')->onDelete('cascade');
$table->foreign('recommended_article_id')->references('id')->on('articles')->onDelete('cascade');
});
usage
$article->recommendations()->attach($articles_ids);
be sure that the ref-column has exact the same type as the source column (signed, unsigned etc.)

How to delete rows from a pivot table in Laravel?

I have a films table which contains a many to many relation e.g AgeRatings with a pivot table called film_age_rating which contains a film_id as a foreign key I have this with 3 other relations too.
Right now my app has no functionality to make a deletion request to remove a film, so right now I hard delete rows in the films DB table. When I delete a film from the films table it deletes items, but the data within the pivot table remains unchanged which I don't want to happen.
films_table
public function up()
{
Schema::create('films', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name')->nullable();
}
film_age_rating
public function up()
{
Schema::create('film_age_ratings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('age_rating_id');
$table->uuid('film_id');
$table->timestamps();
});
}
Film Model
public function ageRatings(): BelongsToMany
{
return $this->belongsToMany(
AgeRatings::class,
'film_age_rating',
'film_id',
'age_rating_id'
);
}
Age Rating Model
public function film(): BelongsToMany
{
return $this->belongsToMany(
Film::class,
'film_age_rating',
'age_rating_id',
'film_id'
);
}
I know an option is to add an onDelete cascade to the pivot tables, but that will require lots of migration tables. Is there another way to tackle this without adding a DELETE request for now or is adding the cascade the only option?
Could you please advise me on the most efficient option?
The only way I can imagine is to use softDeletes
On this way, there will be only one query to delete a film, and it will be a logical delete.
You can delete data using the sync() method. It releases the relation from the pivot table. I assuming that you want to delete a film. So this is a sample method in your controller.
public function deleteFilm($id)
{
$film = Film::find($id);
$film->ageRatings()->sync([]);
$film->delete();
}

Laravel many to many relationship returning empty array

I'm trying to get the results using laravel many to many relationship but the query is generating wrong therefore it return empty array.
$user->survey()->get() is returning empty array.
$user->survey()->toSql() is returning wrong query:
SELECT
*
FROM
`survey`
INNER JOIN `survey_user` ON `survey`.`id` = `survey_user`.`survey_id`
WHERE
`survey_user`.`user_id` IS NULL
Here, in the end, the user_id should not be null.
Migration for the survey pivot table:
Schema::create('survey_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('survey_id')->unsigned();
$table->string('status', 50)->nullable();
$table->timestamps();
});
Schema::table('survey_user', function (Blueprint $table) {
$table->foreign('user_id')->on('users')->references('id');
$table->foreign('survey_id')->references('id')->on('survey')
->onDelete('cascade')
->onUpdate('cascade');
});
}
here are the two relation:
public function survey()
{
return $this->belongsToMany(Survey::class, 'survey_user')
->withPivot('status')
->withTimestamps();
}
public function user()
{
return $this->belongsToMany(User::class, 'survey_user')
->withPivot('status')
->withTimestamps();
}
I'm just trying to get all the users who have survey assigned in their pivot.
$user = new User();
var_dump($user->survey()->get());
I'm just trying to get all the users who have survey assigned in their pivot.
To get all Users where the survey relationship exists, your code would look like this:
$users = User::has('survey')->get();
If you need the survey relationship loaded on the models when you use them, then add with() to eager load the relationship:
$users = User::has('survey')
->with('survey')
->get();
Here, in the end, the user_id should not be null.
The reason it was searching with a null user id is because you are searching with a new User instance that hasn't been saved to the database. This is your code with the problem:
$user = new User();
var_dump($user->survey()->get());
Since $user is a new object that hasn't been saved to the database it doesn't have an id. When you call $user->survey() it builds a query to search survey_user where the user id is null.

Laravel foreign key relation

I've got a strange problem.
I've a users table and a company table. A User belongsTo a company and a company hasMany users.
Both primary keys of the table are id.
In the laravel documentation I read the following:
Additionally, Eloquent assumes that the foreign key should have a
value matching the id column of the parent.
I've got this in my CompanyModel:
protected $table = 'company';
public function users()
{
return $this->hasMany(UserModel::class);
}
When I try this:
$users = CompanyModel::find(1)->users;
dd($users);
It's not working. When I add a foreign key in my relation it works!?:
protected $table = 'company';
public function users()
{
return $this->hasMany(UserModel::class, 'id');
}
This is strange right? What on earth am I doing wrong.
--EDIT--
In my users table I've got a company_id column!
Firstly, I would suggest you rename your Model from CompanyModelto Company and from UserModel to User.
Then ensure you have company_id in your users table. And in your users migration file connect the users table with the companies table as such:
$table->integer('company_id')->unsigned();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
Don't forget to refresh your database.
Then in your models, define the relationships as such:
// User model
// Laravel will automatically identify and use the `company_id` field in your reference
public function company(){
return $this->belongsTo(Company::class);
}
// Company model
public function users(){
return $this->hasMany(User::class);
}
You can then fetch your records in your controller as such:
$user = User::find(1);
$user_company = $user->company; // This might not be necessary in your controller, you can do it in your view
dd($users, $user_company);

Laravel: query many-to-many relationship

I have a User model which belongsToMany() Conferences. Conferences hasMany Users, also a m:m relationship.
I am working on a link() method in my ConferencesController, but I'm not sure how to go about.
I collect the given Conference by id, and the Auth::check-ed User. How do I add the conference and user into the pivot table?
create a pivot table
//conference_user
Schema::create('conference_user', function(Blueprint $table) {
$table->increments('id');
$table->integer('conference_id')->unsigned()->index();
$table->foreign('conference_id')->references('id')->on('conferences');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
now in User model, add this method
public function conferences()
{
return $this->belongsToMany('Conference','conference_user');
}
and in Conference model, add this method
public function users()
{
return $this->belongsToMany('User','conference_user');
}
now in your controller, you can use something like this
$conferences=$user->conferences;
or
$users=$conference->users;

Categories