Laravel: Integrity constraint violation - php

I'm studying some Laravel and at some point I had to re-migrate the database because I had to change a table. I'm using postman to do testing, and one of the api methods give me the error:
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: events.user_id (SQL: insert into "events" ("sport", "title", "players", "when", "description", "location", "updated_at", "created_at") values (Hockey, Grass Hockey, 12, 30/09/2018, Come join us, Fairview park, 2018-11-08 22:19:45, 2018-11-08 22:19:45))
so it seems to be a problem with the events.user_id which I changed on a table called Events to have a relationship with the Users table. Some examples I found by researching is on table fields that were not ids, so I don't how to figure this one out, maybe some of you can help me!
here are the migrations for Events and Users:
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->string('sport');
$table->string('title');
$table->decimal('players', 8, 2);
$table->date('when');
$table->mediumText('description');
$table->string('location');
$table->timestamps();
});
}
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Here are the models:
class Event extends Model
{
protected $fillable = [
'sport',
'title',
'players',
'when',
'description',
'location'
];
public function user()
{
return $this->belongsTo('App\User');
}
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function events()
{
return $this->hasMany('App\Event');
}
}
And below is the api method that is giving me the error:
Route::post('/admin/create-event', function (Request $request) {
$data = $request->all();
$event = Event::create(
[
'sport' => $data['sport'],
'title' => $data['title'],
'players' => $data['players'],
'when' => $data['when'],
'description' => $data['description'],
'location' => $data['location'],
]
);
return $event;
});
Thanks guys!
Edit:
Route::middleware('auth:api')->post('/admin/create-event', function (Request $request) {
$user = $request->user();
$data = $request->all();
$event = Event::create(
[
'user_id' => \Auth::user()->id,
'sport' => $data['sport'],
'title' => $data['title'],
'players' => $data['players'],
'when' => $data['when'],
'description' => $data['description'],
'location' => $data['location'],
]
);
return $event;
});

I think you have to add 'user_id' to $fillable of Event class:
class Event extends Model
{
protected $fillable = [
'sport',
'title',
'players',
'when',
'description',
'location',
'user_id'
];
public function user()
{
return $this->belongsTo('App\User');
}
}

You need to pass the user_id:
'user_id' => \Auth::user()->id
The example above requires an authenticated user in the session, but if you are making the request using postman you probably don’t have one.
Anyway, you need to provide the user_id that will be stored in the database.
EDIT
Eloquent's method create will copy to the model only the attributes defined as fillable. So you have two options:
Add user_id to $fillable
Use newInstance instead of create, manually set the user_id with $event->user_id = ..., and manually save the $event model with $event->save();

Related

Store parent_id in laravel

I'm new to Laravel so I struggle. I have a comment system that worked perfectly fine but now I want to also add a reply system to it. So the way I decided to do it, is by adding a parent_id column to the comments table and then check if a comment has a parent. But I don't know how exactly the store method, in this case, should work. Here's my database set up for comments:
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->text('body');
$table->timestamps();
});
}
And now a set up for the reply column:
public function up()
{
Schema::table('comments', function (Blueprint $table) {
$table->unsignedBigInteger('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('comments');
});
}
Model:
class Comment extends Model{
use HasFactory;
protected $guarded = [];
public function post()
{
return $this->belongsTo(Post::class);
}
public function author()
{
return $this->belongsTo(User::class, 'user_id');
}
public function replies() {
return $this->hasMany('App\Comment', 'parent_id');
}
}
Controller:
public function store(Post $post){
request()->validate([
'body' => 'required'
]);
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('id'),
'body' => request('body')
]);
return back();
}
I just don't know how exactly I can get parent_id in the store function so I would appreciate some suggetstions
it should be the comment id that got the reply
something like this
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('comment_id'),
'body' => request('body')
]);
I hope it's helpful
use code :
public function store(Post $post) {
request()->validate([
'body' => 'required'
]);
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('comment_id'),
'body' => request('body')
]);
return back();
}

Laravel looking for singular table name

when I send data from form to database
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'fypp.joblisting' doesn't exist (SQL: select count(*) as aggregate from `joblisting` where `email` = )
this error occurs. In my database joblistings table exists but laravel looking for the singular name instead of the plural table name. Even I have created new model with new migration and everything but still facing this issue.
model code
class Joblisting extends Model
{
use HasFactory;
protected $fillable = [
'title',
'category',
'company',
'email',
'level',
'number',
'description',
];
}
controller code
class JoblistingController extends Controller
{
public function showForm()
{
return view('frontend.pages.addjob');
}
public function createjob(Request $request)
{
$this->validate($request,[
'title'=> 'required|string',
'category'=> 'required',
'company' =>'required',
'email' => 'required|unique:joblisting',
'level' => 'required',
'number' => 'required',
'description' => 'required',
]);
Joblisting::create([
'title' => $request->title,
'category' => $request->category,
'company'=> $request->company,
'email'=> $request->email,
'level'=> $request->level,
'number'=> $request->number,
'description'=> $request->description,
]);
return redirect('viewlist')->with('success', 'job posted successfully');
}
}
migration code
class CreateJoblistingsTable extends Migration
{
public function up()
{
Schema::create('joblistings', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('category');
$table->string('company');
$table->string('email');
$table->string('level');
$table->string('number');
$table->string('description');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('joblistings');
}
}
You have to use like this
'email' => 'required|unique:joblistings',
Laravel uses snake case, hence:
Fix 1:
use controller name as JobListingController
Fix 2:
in your model, add tthe following line:
protected $table = 'joblistings';

Problem with seeding users to database in Laravel

I am trying to seed users in database but I get error saying
Symfony\Component\Debug\Exception\FatalThrowableError : Call to a member function random() on bool
I have users table and genders table with gender_id in users table that points to Man or Woman column in genders table with hasMany relationship. I want to be able to write gender_id automatically in users table when I seed the database and create a new user. Currently with this code I get that error from above and NULL in gender_id column, but rest it inserts correctly in both users and genders table. When I remove random() function then it inserts always 1 in gender_id, but I want to be able to write 1 or 2 randomly. Also when I dump $genders it returns TRUE. Is there some way around this, any help is appreciated. Here is my code.
UserSeeder.php
<?php
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$genders = DB::table('genders')->insert([
[
'genders' => 'Woman',
],
[
'genders' => 'Woman Looking For Woman',
],
[
'genders' => 'Man',
]
]);
//dd($genders);
DB::table('users')->insert([
'gender_id' => $genders->random(),
'name' => 'authuser',
'email' => 'authuser#auth.com',
'email_verified_at' => now(),
'password' => Hash::make('auth123456'),
'age' => 18,
'remember_token' => Str::random(10),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
}
}
users table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('gender_id')->nullable();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password')->default();
$table->integer('age')->default()->nullable();
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
genders table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGendersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('genders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('genders');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('genders');
}
}
User.php
public function gender()
{
return $this->belongsTo(Gender::class, 'gender_id', 'id');
}
Gender.php
public function users()
{
return $this->hasMany(User::class, 'gender_id', 'id');
}
You can pluck your id values from Gendre and do randomly on that like this:
$genders = DB::table('genders')->insert([
['genders' => 'Woman'],
['genders' => 'Woman Looking For Woman'],
['genders' => 'Man']
]);
$gendreIds = Genders::pluck('id');
DB::table('users')->insert([
'gender_id' => $gendreIds->random(),
...
]);
This will give you gender which exists in database.
Sometimes seed wouldn't give you id's from 1 to 3.
So I think it's not best solution to use rand(1,3).
Good luck!
In your user creation method
Instead of
'gender_id' => $genders->random(),
you can use this
'gender_id' => rand(1,3),
No need to add genders here.You can do that in other seeder or manually do that.Here in your genders id should be in 1,2 & 3 .fixed.THen you can use rand() function here.rand() is a php function .rand() define a random number & you can fixed it value like rand(min,max) so just here use this rand(1,3)
public function run()
{
$genders = DB::table('genders')->insert([
[
'genders' => 'Woman',
],
[
'genders' => 'Woman Looking For Woman',
],
[
'genders' => 'Man',
]
]);//your wish to seed this gender in here
DB::table('users')->insert([
'gender_id' => rand(1,3),
'name' => 'authuser',
'email' => 'authuser#auth.com',
'email_verified_at' => now(),
'password' => Hash::make('auth123456'),
'age' => 18,
'remember_token' => Str::random(10),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
}

Laravel Factory | The mapping is not specified

I'm trying to create some mock data using faker for a Model called Product to test Scout & ElasticSearch but unfortunately, I'm getting an error. When I use factory(App\Product::class, 200)->create() inside of php artisan tinker to generate the data, I get the following error: LogicException with message 'Nothing to update: the mapping is not specified.' Any pointers on which other files I should look at
App > Product.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use ScoutElastic\Searchable;
class Product extends Model {
use Searchable;
protected $indexConfigurator = ProductIndexConfigurator::class;
protected $fillable = ['sku', 'name', 'type', 'price', 'upc', 'category', 'shipping'
, 'description', 'manufacturer', 'model', 'url', 'image'];
public function products ()
{
return $this->belongsTo('App\Product');
}
}
ProductFactory.php
<?php
$factory->define(App\Product::class, function (Faker\Generator $faker) {
return [
'sku' => $faker->randomDigit,
'name' => $faker->name,
'type' => $faker->name,
'price' => $faker->randomDigit,
'upc' => $faker->randomDigit,
'category' => $faker->name,
'shipping' => $faker->randomDigit,
'description' => $faker->name,
'manufacturer' => $faker->name,
'model' => $faker->name,
'url' => $faker->url,
'image' => $faker->url,
];
});
Migration - create_products_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProductTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('product', function(Blueprint $table) {
$table->increments('id');
$table->string('sku');
$table->string('name');
$table->string('type');
$table->string('price');
$table->string('upc');
$table->string('category');
$table->string('shipping');
$table->string('description');
$table->string('manufacturer');
$table->string('model');
$table->string('url');
$table->string('image');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('product');
}
}
Your code is OK and works for me, you're just missing the properties $table and $timestamps on your Product model:
class Product extends Model
{
public $table = 'product';
public $timestamps = false;

laravel create omits/skips fields

I'm trying to seed a couple of databases with laravel seeder, but it seems that it skips some fields..
I'm doing it this way:
Item::create(array(
'name' => 'Category 2',
'photo' => 'Description of category 2',
'order' => 1
'price' => 2.30
'category_id' => 1,
));
The fields 'category_id' and order are not setup in the database..
I'm calling the seeder this way
Artisan::call('db:seed',array('--database' => 'tenant_'.$user, '--class' => 'TenantSeeder'));
Any idea why does it happen?
If I use the standard
$item = new Item;
$item->allfields = "its_value";
$item->save();
It works perfectly
UPDATE
Here comes the model:
<?php
class Item extends Model {
//============================================================================
// PARENT VARIABLES
//============================================================================
protected $table = "items";
protected $softDelete = true;
protected $hidden = ['created_at','updated_at'];
protected $fillable = ['name','price','description','photo']; //Items that can be mass assigned
protected $guarded = array('id');
protected static $rules = [
'name' => 'required|min:3',
'price' => '',
'description' => '',
];
//============================================================================
// METHODS
//============================================================================
public function getId() { return $this->getKey(); }
public function getName() { return $this->name; }
public function getPhotoSrc() { return $this->photo; }
public function item_category(){
return $this->belongsTo('Items_category');
}
public function scopeActive($query)
{
return $query->where('active', '=', true);
}
}
And the Scheme
Schema::create('items', function(Blueprint $table)
{
// auto increment id (primary key)
$table->increments('id');
$table->string('name')->default('New Item');
$table->float('price')->default(0);
$table->string('photo')->nullable();
$table->integer('order')->unsigned();
$table->boolean('active')->default(true);
$table->string('description')->nullable();
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('items_categories')->onDelete('cascade');
// created_at, updated_at DATETIME
$table->timestamps();
$table->softDeletes(); //It is not really deleted, just marked as deleted
});
Any idea?
As User2094178 said,
I didn't have the fields in the $fillable

Categories