Updating a pivot table's additional column in Laravel 4 - laravel

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);

Related

Laravel 8 : SoftDeletes not updated when deleting a user linked to a form

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 ^^'

Has Many Through where the middle table has both forain keys in laravel 5.6

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

Review Schedule Task Code In Laravel 5.1

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

laravel migration best way to add foreign key

Simple question: I'm new to Laravel. I have this migration file:
Schema::create('lists', function(Blueprint $table) {
$table->increments('id');
$table->string('title', 255);
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
I want to update it to add onDelete('cascade').
What's the best way to do this?
Firstly you have to make your user_id field an index:
$table->index('user_id');
After that you can create a foreign key with an action on cascade:
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
If you want to do that with a new migration, you have to remove the index and foreign key firstly and do everything from scratch.
On down() function you have to do this and then on up() do what I've wrote above:
$table->dropForeign('lists_user_id_foreign');
$table->dropIndex('lists_user_id_index');
$table->dropColumn('user_id');
In Laravel 7 it can be done in one line
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
let's say you have two tables student and section , you can refer the following two table structure for adding foreign key and making onDelete('cascade') .
Table -1 :
public function up()
{
Schema::create('student', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('address');
$table->string('phone');
$table->string('about')->nullable();
$table->timestamps();
});
}
Table - 2:
public function up()
{
Schema::create('section', function (Blueprint $table) {
$table->id();
$table->bigInteger('student_id')->unsigned()->index()->nullable();
$table->foreign('student_id')->references('id')->on('student')->onDelete('cascade');
$table->string('section')->nullable();
$table->string('stream')->nulable();
$table->timestamps();
});
}
hope it will help you -:)
you can read the full article from here .
Schema::create('roles',function(Blueprint $table){
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
Schema::create('permissions',function(Blueprint $table){
$table->unsignedBigInteger('role_id');
$table->foreign('role_id')->references('id')->on('roles');
$table->string('permission');
});
As of Laravel 8:
$table->foreignIdFor(OtherClass::class)->constrained();
So simple :)
Make sure that the OtherClass migration file is running EARLIER (by filename date as usual).
If the OtherClass id is not autoincrementing, the otherclass_id would have a type of char instead of bigint, in which case->
Use this instead:
$table->foreignId('otherclass_id')->index()->constrained()->cascadeOnDelete();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
In this example, we are stating that the user_id column references the id column on the users table. Make sure to create the foreign key column first! The user_id column is declared unsigned because it cannot have negative value.
You may also specify options for the "on delete" and "on update" actions of the constraint:
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
To drop a foreign key, you may use the dropForeign method. A similar naming convention is used for foreign keys as is used for other indexes:
$table->dropForeign('posts_user_id_foreign');
If you are fairly new to Laravel and Eloquent, try out the Laravel From Scratch series available on laracasts. It is a great guide for beginners.
Laravel 7.x Foreign Key Constraints
Laravel also provides support for creating foreign key constraints, which are used to force referential integrity at the database level. For example, let's define a user_id column on the posts table that references the id column on a users table:
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
Since this syntax is rather verbose, Laravel provides additional, terser methods that use convention to provide a better developer experience. The example above could be written like so:
Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
});
Source: https://laravel.com/docs/7.x/migrations
You should create a new migration file let's say 'add_user_foreign_key.php'
public function up()
{
Schema::table('lists', function(Blueprint $table)
{
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('lists', function(Blueprint $table)
{
$table->dropForeign('user_id'); //
});
}
The run
php artisan migrate
If you want to add onDelete('cascade') on the existing foreign key, just drop the indexes and create them again:
public function up()
{
Schema::table('lists', function($table)
{
$table->dropForeign('lists_user_id_foreign');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::table('lists', function($table)
{
$table->dropForeign('lists_user_id_foreign');
$table->foreign('user_id')->references('id')->on('users');
});
}
Schema::table('posts', function (Blueprint $table) {
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
for versions before 7x;
Schema::create('lists', function(Blueprint $table) {
$table->increments('id');
$table->string('title', 255);
$table->unsignedBigInteger('user_id')->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
for version 7+;
Since this syntax is rather verbose, Laravel provides additional, terser methods that use conventions to provide a better developer experience. When using the foreignId method to create your column, the example above can be rewritten like so:
Schema::create('lists', function(Blueprint $table) {
$table->increments('id');
$table->string('title', 255);
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
The foreignId method is an alias for unsignedBigInteger while the constrained method will use convention to determine the table and column name being referenced. If your table name does not match the convention, you may specify the table name by passing it as an argument to the constrained method:
Schema::create('lists', function(Blueprint $table) {
$table->foreignId('user_id')->constrained('users')->onDelete('cascade');
});
source: https://laravel.com/docs/7.x/migrations#foreign-key-constraints
Clear and new in laravel
$table->foreignId('book_id')->constrained();
I was doing the same but got error " id not exist" => so I changed my migration file as below :
question table migration content:
$table->id() => should change to $table->increments('id')
definitions of foreign key in Reply table:
$table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');
now your foreign key will work.
Clear, modern and Straightforward approach
suppose parent: `Book Model` and `books table`
suppose child : `Page Model` and `pages table`
$table->foreignId('book_id')->references('id')->on('books');
where book_id is is the colomn name in child (pages table)
and id is the linkage between the Parent and Child tables, books and pages tables, and books is the table name to which we are going to link

How to make N:N relationship in laravel 4

Can anyone help me co build the contact_user ? I need to create two primary keys in this table but, I run this in artisan but does not work. Anybody how to solve this problem?
public function up()
{
Schema::create('users', function($table){
$table->increments('id');
$table->string('name',50);
$table->date('born');
$table->string('email');
$table->timestamps();
});
Schema::create('contact', function ($t){
$t->increments('id');
$t->string('email');
});
Schema::create('contact_user', function ($t){
$t->integer('id_user')->primary();
$t->integer('id_contact')->primary();
$t->foreign('fk_user')->references('id_user')->on('users')->onDelete('cascade')->onUpdate('cascade');
$t->foreign('fk_contact')->references('id_contact')->on('contact')->onDelete('cascade')->onUpdate('cascade');
});
}
This should work but is not tested. Most of it was pulled from the docs and pretty straight forward. I've changed some of the columns to match the naming conventions Laravel is expecting. This makes life much easier when setting up relations, etc...
Check those out at:
public function up()
{
Schema::create('users', function($table) {
$table->increments('id');
$table->string('name',50);
$table->date('born');
$table->string('email');
$table->timestamps();
});
Schema::create('contacts', function ($t) {
$t->increments('id');
$t->string('email');
});
Schema::create('contact_user', function ($t) {
$t->integer('user_id')->unsigned();
$t->integer('contact_id')->unsigned();
$t->primary(array('user_id', 'contact_id'));
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$t->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade')->onUpdate('cascade');
});
}

Resources