I have a column created as follows in my Laravel 4 migration:
public function up()
{
Schema::create(
'templates',
function (Blueprint $table) {
$table->increments('id');
// Omitted fields...
$table->smallInteger('pages')->default(0);
$table->timestamps();
$table->softDeletes();
}
);
}
When I try to save the entity using
$entity->save();
in my controller, I get an error for that particular column when the field value is empty:
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'pages' at row 1
I can fix this by creating a mutator in the model like so:
public function setPagesAttribute($value)
{
if (empty($value)) {
$this->attributes['pages'] = 0;
}
}
But isn't Laravel / Eloquent supposed to be doing that in any case?
I'm just thinking, I'm doing something wrong here...
I've discovered a solution online: http://www.garethalexander.co.uk/tech/mysql-5-incorrect-integer-value-column-id-row-1
Simply do the following:
edit my.cnf
comment out the line
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
And run $ mysql.server restart
The problem is that an empty string is getting passed to the query for the Pages field (the default will only trigger if there's no value being passed for the field). I'm not sure how you're building your entity object, but you basically shouldn't be setting entity->pages at all when you want it to use the default value.
If you're getting pages via Input variables, using either Input::get('pages', 0) or Input::get('pages', null) should fix the problem.
Related
I am trying to switch the primary key of a pivot table from "id" to a combination of two values using a migration inside a laravel project. My up method looks as follows and it works fine:
public function up() {
Schema::table('gallery_image', function (Blueprint $table) {
$table->dropColumn('id');
$table->primary(['image_id', 'gallery_id']);
});
}
However, when I declare the down method in order to undo the above changes like this:
public function down() {
Schema::table('gallery_image', function (Blueprint $table) {
$table->dropPrimary(['image_id', 'gallery_id']);
$table->increments('id');
});
It first gives me an error 1068 Multiple primary key defined, which tells me that the first line in the down method does not work as intended, but when I just run the dropPrimary line, it gives me an error errno: 150 - Foreign key constraint is incorrectly formed.
I am not quite sure as to what I am doing incorrectly.
You could try the following
$table->dropPrimary(); // without the parameters.
Or you could wrap the closure in the down method as following:
DB::statement('SET FOREIGN_KEY_CHECKS=0');
$table->dropPrimary(['image_id', 'gallery_id']);
$table->increments('id');
DB::statement('SET FOREIGN_KEY_CHECKS=1');
or
Schema::disableForeignKeyConstraints();
//code
Schema::enableForeignKeyConstraints();
This will temporarily set the FK Checks off, and turn it back on afterwards.
EDIT
You could look into https://laravel.com/docs/6.0/migrations#dropping-indexes and try out the various functions!
I had data in my database. Now i want to add a column
$table->string('md5_url');
It work. But now i want to add unique index on md5_url. But it don't work because rows in my database have same value(=default value).
So what should i do if i want to create new column form existed column(such as i want md5_url = md5(url_column_value)
I have known 2 way to set default value.
$table->string('md5_url')->default($value);
and
$stack_links = DB::table('stack_links')->update(['md5_url' => $value]);
but 2 above way, the $value is fix, how to make it flexible (diffirent in each row) so that i can add unique index after that.
Note: i don't want to create model StackLink so don't try this way:
$stack_links = StackLink::get();
foreach($stack_links as $stack_link) {
$stack_link->md5_url = md5($stack_link->url);
$stack_link->save();
}
Update: have try
$table->string('md5_url')->default(uniqid());
but it don't work too.The result is
Change your column property like this:
$table->string('md5_url')->nullable();
It's okay now!
Try IGNORE to set unique index to add new column.
public function up()
{
Schema::table('listings', function (Blueprint $table) {
$table->string('md5_url');
});
DB::statement('ALTER IGNORE TABLE listings ADD UNIQUE INDEX myindex (md5_url)');
}
public function down()
{
Schema::table('listings', function (Blueprint $table) {
$table->dropColumn('md5_url');
});
}
I have a few tables where I need tinyint fields which have to be unsigned and set to auto_increment.
The L5.3 Database : Migrations documentation does not have a method to define unsigned auto-incrementing tinyint.
I have tried to implement it using the DB::update(). My migration file for the table looks like:
public function up()
{
Schema::create('table_name', function (Blueprint $table)
{
$table->unsignedTinyInteger('field1');
$table->string('field2', 255);
$table->primary('field1');
$table->index('field2');
$field = "field1";
});
$this->addAutoIncrements($field);
}
public function addAutoIncrements($field)
{
DB::update('ALTER TABLE table_name MODIFY $field TINYINT UNSIGNED NOT NULL AUTO_INCREMENT');
}
When I try php artisan migrate with such a migration file, it migrates without any errors but is not assigning auto-increment.
How do I resolved this? Should I do the update as a complete new migration? Has anyone done it before?
The second parameter for the unsignedTinyInteger() method is a boolean to flag if it is an autoincrementing field. It defaults to false, so you just need to update your migration to pass in true.
$table->unsignedTinyInteger('field1', true);
As a future note, the tinyIncrements() convenience method was added in Laravel 5.4.16 to do exactly that.
I have two table witch named users & Inbox
In the Inbox table I have a column named sender_id that have the user_id of the sender
I want to show this message in the view. I need a query to get the sender_id from the inbox table and use that to select a certain user from the users table
I need to do this with all messages and all users.
Laravel is basicly straith foward when you use eloquent. You can always customise it.
First, almost all the time, I create a model and a migration at the same time using this : php artisan make:model Something --migration
I know you already make some models and/or migrations, but I'll go step by step to help you understand it.
So, in your case, it'll be php artisan make:model User --migration and php artisan make:model Inbox --migration. Doing this, you get two model named User and Inbox and two migration named date_create_users_table.php and date_create_inboxs_table.php. Maybe you already did the default user table with php artisan make:auth. If it's the case, don't remake one.
I'm not sure about how laravel will name the Inbox model migration... Since, I think, Laravel 5.3, the plurialisation changed and don't always just add an "S" at the end.
Then, now you got your models and migrations, let's add some line into your migration files. Since you want to do a one to many relationship. You don't need to touch the user one. Only the Inbox migration. Each Inbox is related to one User and Users can have many Inboxs. Add something like this in your migration:
public function up()
{
Schema::create('inboxs', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
all other columns...
});
}
There, you can change the column's name if you need to have a sender, a recipient, etc... Do this instead :
public function up()
{
Schema::create('inboxs', function (Blueprint $table) {
$table->increments('id');
$table->integer('sender_id');
$table->foreign('sender_id')->references('id')->on('users');
$table->integer('recipient_id');
$table->foreign('recipient_id')->references('id')->on('users');
all other columns...
});
}
What we just did, it's creating the Foreign key that Laravel will use to build the query. There is one last part before the fun one. We need to create the relation in our Model. Begin with the user one:
App/User.php
public function inboxs() {
return $this->hasMany(Inbox::class);
}
And now into the App/Inbox.php model:
public function user() {
return $this->belongsTo(User::class);
}
If you need to have a Sender/Recipient/etc... go this way instead:
public function sender() {
return $this->belongsTo(User::class);
}
public function recipient() {
return $this->belongsTo(User::class);
}
Note that each of your function need to be writen in the same way it's into your migration. sender_id need a relation named sender().
Now, that our relations are done, we can simply call everything using eloquent.
$inboxs = Inbox::with('sender')->get();
This will return an array of all your Inbox into the inboxs table. You can access the sender this way: $inboxs[0]->sender();
You need the id, do this: $sender_id = $inboxs[0]->sender_id;
The sender name : $sender_name = $inboxs[0]->sender->name;
If you want to get one Inbox and you have the id, just do this $inbox = Inbox::with('sender')->find($id);
This way you don't get an array, only one result and can access the sender directly using $sender_name = $inbox->sender->name; instead of having to add [0] or using a foreach loop.
You can get all messages sended by a user using something like this:
$inboxs = Inbox::where('sender_id', $sender_id)->get();
Finally, you can pass your data to the view using:
return view('path.to.view')->with('inbox',$inbox);
Into the view you do this to show the sender's name:
//If view.blade.php
{{$inbox['sender']['name']}} //work a 100%
{{$inbox->sender->name}} //I'm not sure about this one
//If not using blade
<?php echo $inbox['sender']['name']; ?>
There is a lot of thing you can do using Eloquent and you can add as much condition you want. The only thing I suggest you to really do if you want to use Eloquent, be aware about the n+1 problem. There is a link where I explain it. Look for the EDIT section of my answer.
If you need some documentation:
Laravel 5.3 Relationships
Laravel 5.3 Migrations
Laravel 5.3 Eloquent
I think you should update your code like:
$user_messages = DB::table('messages')
->select('messages.id as msgId','messages.message as message','users.id as userId','users.user_name as user_name')
->join('messages','messages.user_id','=','users.id')
->where('messages.user_id',$user_id)
->get();
return view("view.path")
->with('messages',$user_messages);
Hope this work for you!
In Model :
namespace App;
use Illuminate\Database\Eloquent\Model;
class Messages extends Model
{
protected $table = 'table_name';
public function sender()
{
return $this->belongsTo('App\User', 'sender_id', 'id');
}
}
In Controller :
public function functionName($user_id){
$messages = Messages::where('sender_id', $user_id)->get();
return view("view.path")
->with('messages',$messages);
}
In view, you can access seder details like this $message->sender->name for name for id $message->sender->id
I'm having problems with running my migration. I have a mysql database with some tables. The specific table is product_blender. Some fields in the table are like this:
id (PK)
area_id (FK)
inhabitants (varchar)
heating_type_id (FK)
...
Now I would like to create another table called installateur_types. The table needs to contain a PK and a varchar field. I would also like to create a FK in product_blender table to the id of my newly created tabel.
This is what I've done:
Created migration to create a table:
public function up()
{
Schema::create('installateur_types', function(Blueprint $table)
{
$table->increments('id');
$table->string('type');
});
}
public function down()
{
Schema::drop('installateur_types');
}
Run the migration, this was successful. Table was created with correct fields.
Then I've created the migration to add a FK field to the product_blender table.
public function up()
{
Schema::table('product_blenders', function ($table) {
$table->integer('installateurtype_id')->unsigned();
$table->foreign('installateurtype_id')->references('id')->on('installateur_types')->onDelete('cascade');
});
}
public function down()
{
//
}
When I now run the migration I get the following error:
What am I doing wrong?
If your products_blender table is not empty, then when you add a new column which is not null (which is the default for eloquent), it will be assuming some default value on its own. This value may not be available in the table this new column is referring to, causing the foreign key constraint to fail.
One of the way to get around this is to give a default value to the new column or just make it nullable.
$table->integer('installateurtype_id')->unsigned()->nullable();
$table->foreign('installateurtype_id')->references('id')->on('installateur_types')->onDelete('cascade');
There is one other solution, which turns off this checks, which can be done using DB::statement('SET FOREIGN_KEY_CHECKS=0;'). Then again turn that one for future with DB::statement('SET FOREIGN_KEY_CHECKS=1;'). In you code you can do something like
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
$table->integer('installateurtype_id')->unsigned();
$table->foreign('installateurtype_id')->references('id')->on('installateur_types')->onDelete('cascade');
DB::statement('SET FOREIGN_KEY_CHECKS=1;');