I've just started with Laravel and I get the following error:
Unknown column 'updated_at' insert into gebruikers (naam, wachtwoord,
updated_at, created_at)
I know the error is from the timestamp column when you migrate a table but I'm not using the updated_at field. I used to use it when I followed the Laravel tutorial but now that I am making (or attempting to make) my own stuff. I get this error even though I don't use timestamps. I can't seem to find the place where it's being used. This is the code:
Controller
public function created()
{
if (!User::isValidRegister(Input::all())) {
return Redirect::back()->withInput()->withErrors(User::$errors);
}
// Register the new user or whatever.
$user = new User;
$user->naam = Input::get('naam');
$user->wachtwoord = Hash::make(Input::get('password'));
$user->save();
return Redirect::to('/users');
}
Route
Route::get('created', 'UserController#created');
Model
public static $rules_register = [
'naam' => 'unique:gebruikers,naam'
];
public static $errors;
protected $table = 'gebruikers';
public static function isValidRegister($data)
{
$validation = Validator::make($data, static::$rules_register);
if ($validation->passes()) {
return true;
}
static::$errors = $validation->messages();
return false;
}
I must be forgetting something... What am I doing wrong here?
In the model, write the below code;
public $timestamps = false;
This would work.
Explanation : By default laravel will expect created_at & updated_at column in your table.
By making it to false it will override the default setting.
Setting timestamps to false means you are going to lose both created_at and updated_at whereas you could set both of the keys in your model.
Case 1:
You have created_at column but not update_at you could simply set updated_at to false in your model
class ABC extends Model {
const UPDATED_AT = null;
Case 2:
You have both created_at and updated_at columns but with different column names
You could simply do:
class ABC extends Model {
const CREATED_AT = 'name_of_created_at_column';
const UPDATED_AT = 'name_of_updated_at_column';
Finally ignoring timestamps completely:
class ABC extends Model {
public $timestamps = false;
}
Link to laravel documentation https://laravel.com/docs/9.x/eloquent#timestamps
Nice answer by Alex and Sameer, but maybe just additional info on why is necessary to put
public $timestamps = false;
Timestamps are nicely explained on official Laravel page:
By default, Eloquent expects created_at and updated_at columns to exist on your >tables. If you do not wish to have these columns automatically managed by >Eloquent, set the $timestamps property on your model to false.
For those who are using laravel 5 or above must use public modifier other wise it will throw an exception
Access level to App\yourModelName::$timestamps must be
public (as in class Illuminate\Database\Eloquent\Model)
public $timestamps = false;
In case you still want the timestamps, but simply forgot to add them in the migration, adding the following to your migration file, will also work:
class AddUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->timestamps(); // <-- Add this to add created_at and updated_at
});
}
}
Don't forget to re-run your migration afterwards.
php artisan migrate:rollback
php artisan migrate
First Solution
If not necessary created_at and updated_at, please write the below code in the model.
public $timestamps = false;
Second Solution
If you need to use created_at and updated_at in the future, you can add columns.
Create migration file:
php artisan make:migration add_timestamps_fields_to_users_table
Edit migration file:
class AddTimestampsFieldsToUsersTable extends Migration
{
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->timestamps();
});
}
}
Run migration:
php artisan migrate
Related
I have used this code to disable updated_at timestamp
public $timestamps = ['created_at'];
const UPDATED_AT = null;
Now I want to bring it back, I have removed above code, added column, but it's null. Tried to drop migration, migrated with $table->timestamps(), it's still null (on creation and doesn't listen to protected $touches). I have tried public $timestamps = true;, but still null.
My model is that simple:
class Visitor extends Model
{
use HasFactory;
protected $guarded = [];
public function visits()
{
return $this->hasMany(Visit::class);
}
}
Any idea what happened and why I am unable to bring timestamp back?
p.s. I tried clearing cache too
You can also create a migration like this for required table.
$table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
I'm using Laravel 8 and in my application, I have Belongs to Many relations with a custom model, and I want to remove the 'updated_at' field.
Relation
public function tracks()
{
return $this->belongsToMany(Track::class)
->using(CollectionTrack::class)
->withPivot('sort' , 'created_at' , 'id');
}
Custom model
class CollectionTrack extends Pivot
{
use Sortable;
public const UPDATED_AT = null;
public $incrementing = true;
public static function enableAutoSort () {
return false;
}
}
The issue is that when I want to sync, it tries to fill the updated_at field.
Column not found: 1054 Unknown column 'updated_at' in 'field list'
However, I removed the updated_at from the Model using the following line.
public const UPDATED_AT = null;
And also, only get the created_at in withPivot.
When I remove the created_at from withPivot, the issue goes away, but in that case, when I retrieve the data created_at won't be in the fields.
Note: my goal is to disable the updated_at timestamp and only have created_at so when I attach a new record, the created_at set and when I retrieve it, the model has these pivot fields 'sort', 'created_at', 'id.'
I think you can remove $table->timestamps() from your migration and just add a field created_at having default value current time stamp.
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
should work I guess.
There is another answer you can refer.
You either have to declare public $timestamps = false; in every model, or create a BaseModel, define it there, and have all your models extend it instead of eloquent. Just bare in mind pivot tables MUST have timestamps if you're using Eloquent.
Update: Note that timestamps are no longer REQUIRED in pivot tables after Laravel v3.
Update: You can also disable timestamps by removing $table->timestamps() from your migration
ORIGINAL ANSWER: https://stackoverflow.com/a/59171175/14290461
In your model add these two lines:
public $timestamps = ["created_at"]; //only want to used created_at column
const UPDATED_AT = null; //and updated by default null set
second way:
public $timestamps = false; //by default timestamp false
add function like this:
public function setCreatedAtAttribute($value) {
$this->attributes['created_at'] = \Carbon\Carbon::now();
}
for more info about laravel timestamp see
I need an effective way to disable Laravel from auto incriminating the primary key of the table which I am going to insert data in.
Why? I don't check if there is any duplication between the DB and the inserted data so if there was any duplication I just handles it in a try-catch block.
The problem is if there was any failure Laravel counts it like I have inserted a row. So IDs column is not going to be in this order [1, 2, 3, etc], but in this [1, 4, 8, 20, etc].
I searched a lot about this issue and I have tried to use this line after the declaration of the class:
public $autoincrement = false;
Also
public $incrementing = false;
But they are not working.
I just want to use the AI of my DB. Not Laravel's one.
if you wish to use a non-incrementing or a non-numeric primary key you must set the public $incrementing property on your model to false.
eg :
class UserVerification extends Model
{
protected $primaryKey = 'your_key_name'; // or null
public $incrementing = false;
}
in case of migration :
$table->integer('id')->unsigned(); // to remove primary key
$table->primary('id'); //to add primary key
refer : https://laravel.com/docs/5.3/eloquent#eloquent-model-conventions
Try public $incrementing = false;
In your model:
public $incrementing = false;
In your migration:
//Remove the default $table->id();
//second param is what auto-increments, default is false so can be skipped
$table->unsignedBigInteger('id', false)->primary();
A quick comment on all the other outdated or wrong solutions you see here:
$primaryKey does not need to be overridden unless the primary column is different than 'id'
You do not need to use the ugly DB transaction just to remove auto-incrementing! Keep using the lovely eloquent models and just use this answer.
There are 2 solutions to your problem.
First one is, as you said, disable the increment column. To do that, just go to your migrations, and change
$table->increment('id)`
to
$table->integer('id')
It will remove the primary key, to set the primary key, just go to your Model file and add this:
protected $primaryKey = 'column_name';
Second solution is what I prefer. Whenever inserting, updating or removing a record and even sometimes reading a record, use laravel's DB transaction. Here is an example:
DB::beginTranscation();
try {
$model = new Model;
$model->column_name = $value;
$model->save();
DB::commit()
return;
}
catch(exception $e) {
DB::rollback();
return;
}
This approach is better than remove the auto increment. But now it's upto you to choose.
You have to declare your new primary key in your table migration file:
$table->primary('new_key_column');
Of course you have to disable autoincrement in your model as you did.
You can do something like below
Table: author
Columns: id, name, active
class Author extends Model
{
/**
* Configure the Model variables
*
*/
protected $table = 'author';
protected $primaryKey = 'id';
protected $fillable = ['name', 'active']; // eloquent Will use only these columns as you are mentioning them as fillable.
public static function saveAuthor($data) {
$author = Author::firstOrNew(['name' => $data['name']]);
$author->name = $data['name'];
$author->active = 1;
$author->save();
}
}
Here in fillable you define the columns that you want to change or update through model. Rest fields behaviour will take according to mysql definition.
I hope this will help you.
*/ please test this one
public function up()
{
Schema::create('tablename', function (Blueprint $table) {
// $table->increments('id');
$table->integer('id')->unsigned()->nullable();
$table->string('name');
$table->string('info');
$table->timestamps();
});
}
// note:
add below line in model
public $incrementing = false;
This is an example for table created its name site_rules and this is the migration file which i add the following line to make id primary and auto incremented
//add this line to make id auto incremented from a specified value
DB::statement("ALTER TABLE site_rules AUTO_INCREMENT = 1;");
and this is the migration file code :
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class SiteRules extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('site_rules', function (Blueprint $table){
$table->increments('id');
$table->string('name_ar');
$table->string('name_en');
$table->timestamps();
});
//add this line to make id auto increment from a specified value
DB::statement("ALTER TABLE site_rules AUTO_INCREMENT = 1;");
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('site_rules');
}
}
Try it
Sorry for taking your time guys,
The issue is if we tried to save any record in MYSQL whether it returned success or failure for any reason (like for duplication in my case),
MYSQL counts that the auto increment number was booked and any other coming record is not going to take it because of there may be more than an insertion process on the DB in the same time and waiting to know if the auto incrementally number is booked or not will cost MYSQL its speed.
So it is not a Laravel issue, its a MYSQL one.
I hope that it may help others.
Thank you all...
You can use
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->integer('matricule')->unsigned();;
$table->primary(['matricule']);
$table->string('nometprenom');
$table->string('age');
$table->string('adresse');
$table->string('telephone');
$table->string('login');
$table->string('password');
$table->string('type');
$table->engine = 'InnoDB';
});
}
I come here cause i have an issue with Eloquent relations One To Many, i've tested a lot since a week now but nothing to do. I try here for my last chance, after this, i will try Database: Query Builder, but i will prefer to perform my code with Eloquent.
To make simple, i want to show the differents furnitures use with the id task, so a task hasMany furnitures.
So i give you the problem, i made the relation into my model, when i call the function HasMany, it's returned to me an empty object...
I use php artisan tinker on git bash but after a thousand of try, it's not working.
I show you my try with GitBash and after my code.
When i do this ">>> $comments = App\BonIntervention::find(2003);"
Tinker show me the right thing, the id "2003" to my Table related to my model, with all his components. But when i do this after:
"$comment = $comments->bonInterventionFournitures"
I'have this answer "Illuminate\Database\Eloquent\Collection {#810
all: [],
}"
And for a lot of try with different name/method his always the same, like my table are empty, but they're not....
Here you have my model for the "task", When i read the doc Laravel eloquent HastoMany, it appears that you can pass to the return, for the first parameter the namespace, for the second parameter the foreign key of the table, and for third parameter the primary key. So i did like this, i hope i didn't mistake myself.
namespace App;
use Illuminate\Database\Eloquent\Model;
class BonIntervention extends Model
{
protected $primaryKey = 'Id_TTa';
protected $table = 'T_Taches';
public $timestamps = false;
public function bonInterventionFournitures(){
return $this->hasMany('App\BonInterventionFournitures', 'Id_TTa', 'Id_TTaDFo');
}
}
Now it's the model for furnitures. (Same method for the parameters in the return)
namespace App;
use Illuminate\Database\Eloquent\Model;
class BonInterventionFournitures extends Model
{
protected $table = 'T_Taches_Details_Fournitures';
protected $primaryKey = 'Id_TTaDFo';
public function bonInterventions(){
return $this->belongsTo('App\BonIntervention', 'Id_TTa', 'Id_TTa');
}
}
I can show you my migrations for this table.
First, the table task (i not show you the entire table, because it's a lot of information.
public function up()
{
Schema::create('T_Taches', function(Blueprint $table)
{
$table->integer('Id_TTa', true);
$table->string('Responsable_TCa')->nullable()->index('Responsable_TCa');
$table->dateTime('Date_TTa')->nullable()->default('0000-00-00 00:00:00');
$table->string('Ste_TCl')->nullable()->index('Ste_TCl');
$table->string('Ste_Utl')->nullable()->index('Ste_Utl');
$table->string('Adr_Liv_TCl')->nullable()->index('Adr_Liv_TCl');
$table->string('Contact_TCo')->nullable()->index('Contact_TCo');
$table->string('Collaborateur_TCa')->nullable()->index('Collaborateur_TCa');
$table->string('NDevis_TDv')->nullable()->index('NDevis_TDv');
$table->string('Devis_Type_TTa')->nullable();
$table->string('NCommande_TDv')->nullable()->index('NCommande_TDv');
$table->dateTime('Date_Debut_TTa')->nullable();
$table->dateTime('Date_Fin_TTa')->nullable();
$table->dateTime('Date_Demande_TTa')->nullable();
Now the furnitures table
public function up()
{
Schema::create('T_Taches_Details_Fournitures', function(Blueprint $table)
{
$table->integer('Id_TTaDFo', true);
$table->integer('Id_TTa')->nullable()->index('Id_TTa');
$table->string('Class_TTaDFo')->nullable();
$table->string('Des_TTaDFo')->nullable();
$table->string('Ref_TTaDFo')->nullable();
$table->float('Qte_TTaDFo', 10, 0)->nullable()->default(0);
$table->float('PAHT_TTaDFo', 10, 0)->nullable()->default(0);
$table->float('Tx_Mge_TTaDFo', 10, 0)->nullable()->default(1.5);
$table->float('Vente_HT_TTaDFo', 10, 0)->nullable()->default(0);
});
}
I hope you understand my question, and thanks all for watching.
SOLVED
I solved this and i explain why on the answer, after my post.
I've found the solution. In fact in my models i erase the second and third parameters.
return $this->belongsTo('App\BonIntervention', 'Id_TTa', 'Id_TTa');
return $this->hasMany('App\BonInterventionFournitures', 'Id_TTa', 'Id_TTaDFo');
I just add the second parameter in my return hasMany, just like this
return $this->hasMany('App\BonInterventionFournitures', 'Id_TTa');
return $this->belongsTo('App\BonIntervention');
Now with artisan tinker when i do this
$comments = App\BonIntervention::find(2003);
$comment = $comments->bonInterventionFournitures;
I find the right answer.
I have a save method where I do validation, create a model and save it. Later in the save method I try and access the ID of the model and it's NULL.
Schema:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('body');
//and other fields that aren't important right now
$table->timestamps();
});
}
Save method:
public function savePost(Request $request) {
$this->validate($request, [
//some validation happens here
]);
$post = new Post();
$title = $request->input('title');
$body = $request->input('body');
$post->title = $title;
$post->body = $body;
$post->save();
//I later try to access the $post->id here and it's still NULL.
var_dump($post->id);//NULL
}
In MySQL the ID is being set (just an auto incrementing unsigned integer) - it seems like it gets set after the savePost method is complete.
I thought that after $post->save() was complete, the model's ID would be set - but that seems to not be the case. How can I access the model's ID from the same method where I save() it? Or have I made a mistake somewhere?
Laravel Framework version is 5.3.26
Edit: just to clarify: the model (including the auto incrementing PK) is being stored in MySQL, I'm just not able to access the model's id in the same method that I save it.
Figured it out:
I ran into this issue when switching from a string PK to an auto incrementing unsigned int.
I still had public $incrementing = false; in the Post model, which explains this issue. Switching to $incrementing = true solved the problem.
For other people how are using Pivot/Junction table, hence, if your model is extending Pivot instead of Model then this is why,
As #noob mentioned, You've to enable public $incrementing = true; manually or just extend Model instead.