I am writing a code to be scheduled to run occasionally. I want to remove records of users who have their details on the users table but does not have their records in the profiles table as well. I am thinking about removing the by their id, but I am not sure how I can make the match. profiles migration:
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('gender',5);
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); // When a profile is deleted- his corresponding associated id details are deleted as well.
$table->tinyInteger('age')->unsigned()->nullable();
$table->string('goals')->nullable();;
$table->string('activityType')->nullable();
$table->rememberToken(); // for remember me feature.
});
}
Users migration:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('username',20)->unique();
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
I have started to write the query, yet I am not sure how to proceed.
public function handle()
{
// type the query to get users that have no data in their profiles.
$empty_profile=App\Profile:::where('id','')->get;
$user_id=App\User::where('id')
}
Appreciate your help. Thanks.
Although your example is not exactly clear to me (and I wonder why there would be users without profiles in the first place?) I think this is what you need:
public function handle()
{
$empty_profiles = App\User::doesntHave('profile')->delete();
}
This will work if the models are correctly connected see also:
https://laravel.com/docs/master/eloquent-relationships
Related
I have a problem on Laravel 8 when I delete a user I have my 'deleted_at' which is updated in my 'user' table but not the 'deleted_at' of my 'forms' table because I want to delete the forms linked to this user otherwise I have an error because I display his info when he does not exist anymore.
How do I fix this problem please?
I have used the soft delete in the Models
and the 'deleted_at' is updated when I delete the form.
users migration :
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('firstname');
$table->string('lastname');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable()->onDelete('cascade');
$table->string('profile_photo_path', 2048)->nullable();
$table->timestamps();
$table->foreignId('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->softDeletes();
});
}
public function down()
{
Schema::dropIfExists('users', function (Blueprint $table) {
$table->dropColumn('deleted_at');
});
}
forms migration :
public function up()
{
Schema::create('forms', function (Blueprint $table) {
$table->id();
$table->string('title', 100);
$table->text('message');
$table->datetime('date');
$table->string('color');
$table->softDeletes();
$table->timestamps();
});
}
public function down()
{
// Schema::dropIfExists('forms');
Schema::table('forms', function (Blueprint $table) {
$table->dropColumn('deleted_at');
});
}
add user to forms migration :
public function up()
{
Schema::table('forms', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::table('forms', function (Blueprint $table) {
$table->dropForeign('user_id')->onDelete('cascade');
});
}
Soft delete won't work on cascading foreign keys. Cascading foreign keys is a feature of sql servers and soft delete is a feature of laravel and needs the laravel context to work.
When you delete it, for the soft deletes to work, you need to call delete on each model of the relation. This is quite easy with collections and higher order functions.
{
$user = User::firstOrFail($id);
$user->forms->each->delete();
$user->delete();
...
}
Thank you very much mrhn,
Thanks to you I have learned a lot!
For those which want the function in the controller which thus makes it possible to remove the user to which belongs thus the id and one thus removes also what is related to him in my case a forms (function in the Models for the cardinalities between entity) :
public function destroy($id)
{
// $users = User::findOrFail($id);
// $users->delete();
$user = User::findOrFail($id);
$user->forms->each->delete();
$user->delete();
return redirect()->route('admin');
}
findOrFail and not firstOrFail ^^'
I think I am doing this correctly. I have a users, profile, and application table. Below are the migrations. I think I am linking them correctly in the migration but need advice to make sure. 1 user can have 1 profile but many applications.
User Table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Profile Table
public function up()
{
Schema::create('profile', function (Blueprint $table) {
$table->id();
$table->integer('user_id')->unsigned();
$table->string('address')->nullable();
$table->string('apt')->nullable();
$table->string('city')->nullable();
$table->string('state')->nullable();
$table->string('zipcode')->nullable();
$table->string('homephone')->nullable();
$table->string('mobile')->nullable();
$table->string('occupation')->nullable();
$table->boolean('over18')->nullable();
$table->string('homechurch')->nullable();
$table->string('homechurchcity')->nullable();
$table->string('pastor')->nullable();
$table->string('howoftenattend')->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
Application
public function up()
{
Schema::create('pilgrim_application', function (Blueprint $table) {
$table->id();
$table->string('besttimetocall');
$table->string('nickname');
$table->foreignId('user_id')->constrained('users')->onDelete('cascade');
$table->foreignId('profile_id')->constrained('profile')->onDelete('cascade');
$table->timestamps();
});
Does your migration work at the moment?
First check your migration file order, for example
0000_user
0001_profile
1000_ pilgrim_application
1001_app_two
in case of multiple applications you could begin the migration with a different number for grouping files in a list, this can be handy if you want to create multiple applications.
Also, is it necessary to specify the relations user and profile in the pilgrim_application migration?
Through relationships in your models you can also access the pilgrim_application from the user model and vice versa.
$user->profile->pilgrim_application
I need to make a HasManyThough relation where the middle Model holds the foreign keys of both Models.
Here is detail:
Migrations:
Schema::create('carriers', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
});
Schema::create('shipping_zones', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
});
Schema::create('shipping_rates', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('shipping_zone_id')->unsigned()->index();
$table->integer('carrier_id')->unsigned()->index();
$table->decimal('rate', 20, 6);
});
Now I need something like
$carrier->shippingZone()
Is there any easy way to get this?
As per your migrations you need Many To Many relation rather than the HasManyThough relation.
Carrier.php
public function shippingZones()
{
return $this->belongsToMany('App\ShippingZone', 'shipping_rates);
}
You can access all shipping zones related to the carrier using, $carrier->shippingZones.
If you need to chain the query you can use $shippingZones = $carrier->shippingZones()->orderBy('id')->get(); here
If you need to use HasManyThough you would have to change the migrations. here
I'm quite new to programming and am struggling to understand how I should specify the eloquent relationships.
I've created a website where there is an event called a "hangout" and a "join" button which allows users to join the event, thereby attaching their user_id to the hangout_id via a pivot table.
Right now I'm very confused as to how I should/can:
specify the relationships between hangout and users;
for a single hangout, display a list of users attending;
for a single user, display a list of hangouts created; and
for a single user, display a list of hangouts they are attending?
Users can create many hangouts, i.e. hasMany, but when they click "join", they also belongToMany hangouts.
Whilst hangouts can only belong to one user but can have many attendees/users.
Can someone point me in the right direction? This is what I have so far...
User.php
public function hangouts()
{
return $this->hasMany('App\Hangout');
}
public function attending()
{
return $this->belongsToMany('App\Hangout');
}
Hangout.php
public function user()
{
return $this->belongsTo('App\User');
}
public function attendees()
{
return $this->hasMany('App\User');
}
Users Table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
$table->boolean('admin');
});
}
Hangout Table:
public function up()
{
Schema::create('hangouts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title');
$table->string('description');
$table->integer('price')->unsigned();
$table->timestamp('published_at');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
Schema::create('hangout_user', function(Blueprint $table)
{
$table->integer('hangout_id')->unsigned()->index();
$table->foreign('hangout_id')->references('id')->on('hangouts')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
}
Thanks in advance
I have the following schema:
public function up()
{
Schema::create('messages', function(Blueprint $table) {
$table->increments('id');
$table->mediumText('subject');
$table->text('message');
$table->boolean('draft');
$table->integer('sender_id')->unsigned();
$table->softDeletes();
$table->timestamps();
$table->foreign('sender_id')->references('id')->on('users')->onUpdate('cascade');
});
Schema::create('message_assets', function(Blueprint $table) {
$table->increments('id');
$table->integer('message_id')->unsigned();
$table->string('filename', 255);
$table->softDeletes();
$table->foreign('message_id')->references('id')->on('messages')->onUpdate('cascade');
});
Schema::create('message_users', function(Blueprint $table) {
$table->increments('id');
$table->integer('message_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->integer('read')->default(0);
$table->string('folder', 255)->nullable();
$table->softDeletes();
$table->foreign('message_id')->references('id')->on('messages')->onUpdate('cascade');
$table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade');
});
}
What I would like to do is update the read column in the pivot table to true when the user view the message. I have the controller nailed its just how do I go about getting the relevant record from the pivot and update the read field only.
Here is the relationship:
public function to()
{
return $this->belongsToMany('SeriousJelly\Modules\Users\Models\User', 'message_users', 'message_id', 'user_id');
}
I am a little unclear on exactly what you want. A little controller code might be nice to see what you have tried and what you are trying to do.
That said, this may work.
$message->to()->updateExistingPivot($user_id, ['read'=> 1]);
Using to is a little ambiguous, i might use user to make it a bit more clear assuming this is on the Message model.
The docs have some good information.
UPDATE PER COMMENT
The code below works in Laravel 5 but I am not sure with 4.2.
$message->to()->sync([$user_id => ['read'=> 1]], false);