// the ticket migration
Schema::create('tickets', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('title');
$table->text('body');
$table->timestamps();
});
// ticket and status
Schema::create('statuses', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('ticket_status', function (Blueprint $table) {
$table->integer('ticket_id')->unsigned();
$table->integer('status_id')->unsigned();
$table->primary(['ticket_id','status_id']);
});
// store method
public function store()
{
$this->validate(request(), [
'title' => 'required',
'body' => 'required |min:5'
]);
auth()
->user()
->tickets()
->create(request(['title','body','group','status','priority']));
return redirect('/');
}
I have migration for my tickets and I have to get status_id and ticket_id.
When I use create method in my controller table status_ticket do not fill with data.
I do not have an error but my table is empty.
Try to use save, not create. Then the model should be attached
Have you used the methods belongsTo() and hasMany() in your new models?
If not, you have to add these and then you can easily save relations.
Related
I'm running Laravel 7 on PHP 7.4 with MySQL 8.0.
I have three tables, User, Company and Department, with their respective models and factories.
I created a test where I'm adding the relationship:
// MyTest.php
$user = factory(User::class)->create();
$company = factory(Company::class)->make();
$company->user()->associate($user);
$company->create(); // it fails here because of NOT NULL constraint, companies.user_id
$department = factory(Department::class)->make();
$department->company()->associate($company);
$department->create();
I get the following error: Integrity constraint violation: 19 NOT NULL constraint failed: companies.user_id (SQL: insert into "companies" ("updated_at", "created_at") values (2020-03-10 07:27:51, 2020-03-10 07:27:51))
My table schema is defined like this:
// users
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('phone');
$table->integer('user_type');
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
// companies
Schema::create('companies', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->string('contact_email');
$table->string('contact_phone');
$table->timestamps();
});
// departments
Schema::create('departments', function (Blueprint $table) {
$table->id();
$table->foreignId('company_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->string('contact_email');
$table->string('contact_phone');
$table->timestamps();
});
It is my understanding that there should be no NULL-values in SQL-tables, which is why I am deliberately trying to avoid ->nullable() in my migrations. Especially for foreign keys like these.
EDIT:
I tried doing it this way, I also made a pivot table for users_companies. Now I can attach a company, but I'm still getting an SQL-error when doing the test this way:
$user = factory(User::class)->create();
$company = factory(Company::class)->create();
$user->companies()->attach($company);
$company->departments()->create([
'name' => 'Department 1',
'contact_email' => 'department1#example.test',
'contact_phone' => '123456789',
]);
This also fails with the error stated below:
$company = factory(Company::class)->create();
$company->departments()->save(factory(Department::class)->make());
The error is this: Integrity constraint violation: 19 NOT NULL constraint failed: departments.company_id (SQL: insert into "departments" ("name", "contact_email", "contact_phone", "company_id", "updated_at", "created_at") values (Department 1, department1#example.test, '123456789', ?, 2020-03-11 07:59:31, 2020-03-11 07:59:31)).
CompanyFactory.php
<?php
/** #var \Illuminate\Database\Eloquent\Factory $factory */
use App\Company;
use Faker\Generator as Faker;
$factory->define(Company::class, function (Faker $faker) {
return [
'name' => 'Company 1',
'contact_email' => 'company#example.test',
'contact_phone' => '123456789',
];
});
Factories
DepartmentFactory.php
<?php
/** #var \Illuminate\Database\Eloquent\Factory $factory */
use App\Department;
use Faker\Generator as Faker;
$factory->define(Department::class, function (Faker $faker) {
return [
'name' => 'Department 1',
'contact_email' => 'department1#example.test',
'contact_phone' => '123456789',
];
});
Some problems with your table structure are very clear at first glance.
It appears you're trying to add a user_id column to your companies table. This is not a good idea, assuming your companies have more than one employee.
If you want to use NOT NULL columns, you'd better define a default value for each of them.
So we can start by writing the migrations something like this, including pivot tables for the company/user and department/user relationships:
// companies
Schema::create('companies', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('contact_email')->default('');
$table->string('contact_phone')->default('');
$table->timestamps();
});
// departments
Schema::create('departments', function (Blueprint $table) {
$table->id();
$table->foreignId('company_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->string('contact_email')->default('');
$table->string('contact_phone')->default('');
$table->timestamps();
});
// users
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('name')->default('');
$table->string('phone')->default('');
$table->integer('user_type')->default(0);
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::create('company_user', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('company_id')->constrained()->onDelete('cascade');
});
Schema::create('department_user', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('department_id')->constrained()->onDelete('cascade');
});
Now we have links between tables. A department is part of a company; a user can be part of multiple departments and/or multiple companies. This leads to the following relationships:
class User extends Model {
// many-to-many
public function companies() {
return $this->belongsToMany(App\Company::class);
}
// many-to-many
public function departments() {
return $this->belongsToMany(App\Department::class);
}
}
class Company extends Model {
public function departments() {
// one-to-many
return $this->hasMany(App\Department::class);
}
public function users() {
// many-to-many
return $this->belongsToMany(App\User::class);
}
}
class Department extends Model {
public function company() {
// one-to-many (inverse)
return $this->belongsTo(App\Company::class);
}
public function users() {
// many-to-many
return $this->belongsToMany(App\User::class);
}
}
Now code like this should work:
$user = factory(User::class)->create();
$company = factory(Company::class)->create();
$user->companies()->attach($company);
$company->departments()->create([
'name' => 'Department 1',
'contact_email' => 'department1#example.test',
'contact_phone' => '123456789',
]);
Specifically, the attach method is used for updating many-to-many relationships, which you did not appear to have defined, based on your original table layout.
I have 3 models:
User
Company
Enquiry
A user can own more than one company, a company can only belong to one user. An enquiry can belong to many companies and a company can have many enquiries.
The migrations look as follows:
User migration
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('contact_number');
$table->longText('address')->nullable();
$table->integer('postal_code');
$table->string('activation_token')->nullable();
$table->boolean('active')->default(false);
$table->enum('type', ['Admin', 'End User', 'Service Provider', 'Broker']);
$table->string('password')->nullable();
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
Company Migration
Schema::create('companies', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('service_provider_id')->nullable();
$table->unsignedInteger('broker_id');
$table->string('name');
$table->string('email')->unique()->nullable();
$table->string('contact_number');
$table->longText('address')->nullable();
$table->integer('postal_code');
$table->enum('status', ['Confirmed', 'Declined', 'New'])->default('New');
$table->timestamps();
$table->softDeletes();
});
Schema::table('companies', function (Blueprint $table) {
$table->foreign('service_provider_id')->references('id')->on('users');
$table->foreign('broker_id')->references('id')->on('users');
});
Enquiries Migration
Schema::create('enquiries', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('end_user_id');
$table->unsignedInteger('category_id');
$table->string('title');
$table->longText('description');
$table->integer('radius');
$table->enum('status', ['New', 'In Progress', 'Complete'])->default('New');
$table->timestamps();
});
Schema::table('enquiries', function (Blueprint $table) {
$table->foreign('end_user_id')->references('id')->on('users');
$table->foreign('category_id')->references('id')->on('categories');
});
CompanyEnquiry Migration
Schema::create('company_enquiry', function (Blueprint $table) {
$table->integer('company_id')->unsigned()->index();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
$table->integer('enquiry_id')->unsigned()->index();
$table->foreign('enquiry_id')->references('id')->on('enquiries')->onDelete('cascade');
$table->primary(['company_id', 'enquiry_id']);
});
I have set up the various relationships in their respective models.
What I'm trying to achieve is query the database to retrieve only those enquiries which belong to the user via the company.
How can I achieve this?
Something like this (add the real model, relation names ans columns):
$enquiries = Enquiries::whereHas(['companies' => function($query){
$query->whereHas(['user' => function($query){
$query->where('id', $user_id);
}]);
})
->get();
You could do it this way with shorter code.
$enquiries = Enquiries::whereHas('companies.user', function($query) use($user_id){
$query->where('id', $user_id);
})->get();
I'm trying to use a belongsToMany relation, i never had any problems with it but for some reason it returns empty.
I've set up my relation in the Store model like this:
public function images()
{
return $this->belongsToMany('App\Images', 'images_stores', 'image_id', 'store_id');
}
When i test the relationship it returns no error just a empty collection although it's not. This is the way i access the data:
public function edit($id)
{
$store = Store::find($id);
dd($store->images);
return view('admin.pages.store.edit', compact('store'));
}
But it would just return a empty collection, i hope someone could help me out with this. These are my migration file's but i don't think the problem is inside the migration files.
Schema::create('images', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('path');
$table->timestamps();
});
// pivot table
Schema::create('images_stores', function (Blueprint $table) {
$table->increments('id');
$table->integer('image_id')->unsigned()->nullable();
$table->foreign('image_id')->references('id')->on('images')->onDelete('cascade');
$table->integer('store_id')->unsigned()->nullable();
$table->foreign('store_id')->references('id')->on('stores')->onDelete('cascade');
$table->timestamps();
});
// store table
Schema::create('stores', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('location');
$table->string('email');
$table->timestamps();
});
Thanks guys.
I think the ids are inverted. Try this:
public function images()
{
return $this->belongsToMany('App\Images', 'images_stores', 'store_id', 'image_id');
}
I have this code right there, this code is working fine and data is successfully stored to table "reports". But I also want to update Users table and their field Credits also. How can I do this in this function ? I also have the relationship between these two tables "reports" and "users".
public function giveCredits($id)
{
$report = Report::where('id', $id)->first();
$report->credits += Input::get('credits');
$report->save();
return redirect()->back();
}
Users Table
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('email')->unique();
$table->string('password');
$table->integer('credits');
$table->enum('role', ['user', 'admin'])->default('user');
$table->rememberToken();
$table->timestamps();
});
Reports table
Schema::create('reports', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->integer('credits');
You just need to add the logic to update the user (assuming you have a relationship method called user):
public function giveCredits($id)
{
$report = Report::where('id', $id)->first();
$report->credits += Input::get('credits');
// if the report has a user, update it
if ($report->user) {
$report->user->credits += Input::get('credits');
$report->user->save();
}
$report->save();
return redirect()->back();
}
I currently have a Users to Groups Relationship (ManyToMany) with a pivot table group_user. I want the user to be able to create a group but once creating the group, how do I make it, that the creator becomes member of this group?
Currently I have
My Pivot Table (group_user):
Schema::create('group_user', function(Blueprint $table)
{
$table->integer('group_id')->unsigned()->index();
$table->foreign('group_id')->references('id')->on('groups')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
My Groups table (groups):
Schema::create('groups', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->timestamps();
});
My Users table (users):
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('username')->unique();
$table->string('email')->unique();
$table->string('name');
$table->string('lastname');
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
My models ofcourse have the following: User.php
public function groups()
{
return $this->belongsToMany('App\Group');
}
Group.php
public function users()
{
return $this->belongsToMany('App\User');
}
What create function should I write in my controller so that when a User creates a Group, that he automaticly becomes member of this group (automaticlly make the pivot relationship)?
This should work, make sure you implement validation, ect.
public function store(Request $request)
{
$group = Group::create([ // <-- if names are unique. if not, then create is fine
'name' => $request->get('name')
]);
auth()->user()->groups()->attach([$group->id]);
return view('your.view');
}
Also make sure to add:
use App\Group;
See attach() and detach().
$user = User::find(1);
$user->groups()->attach(10); // pivot relationship of this user to group of id 1.
OR
$group = Group::find(10);
$user->groups()->save($group);
For many groups of this user:
$user->groups()->sync(array(1, 2, 3));