Database Relationship with Laravel - php

i am having trouble inserting data into my database according to my database structure. I have 3 tables. Company table Users table branches table.
Now this is how i made the relationship between these tables.
Company table and Users table have one to many relationship
Company table and Branches table have one to many relationship
Branches table and Users table have one to many relationsip
This is how my model looks like
PS: I am only a beginner with database and laravel
Company Model
public function branches()
{
return $this->hasMany('App\Branch');
}
public function users()
{
return $this->hasMany('App\User');
}
User Model
public function company()
{
return $this->belongsTo('App\Company')
->withTimestamps();
}
public function branches()
{
return $this->belongsTo('App\Branch')
->withTimestamps();
}
Branch Model
public function company()
{
return $this->belongsTo('App\Company');
}
public function users()
{
return $this->hasMany('App\User');
}
Now, when a user registers, only the company table is filled with it details but the user table and branch table is not filled and i get the error
"SQLSTATE[HY000]: General error: 1364 Field 'company_id' doesn't have a default value (SQL: insert into `branches` (`name`, `updated_at`, `created_at`) values (Virginia, 2017-10-14 03:19:38, 2017-10-14 03:19:38)) ◀"
This is how i save the data in the RegisterController
RegisterController
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'phone' => $data['phone'],
'password' => bcrypt($data['password']),
"company_id" => Company::create(
[
"name" => $data['rname'],
"email" => $data['remail'],
"phone" => $data['rphone'],
"address" => $data['raddress']
]
)->id,
"branch_id" => Branch::create (
[
"name" => $data['rbranch']
]
)->id
]);
}

You should try this may be its help for you:
protected function create(array $data)
{
$company = Company::create(
[
"name" => $data['rname'],
"email" => $data['remail'],
"phone" => $data['rphone'],
"address" => $data['raddress']
]);
Updated Answer
$branch = Branch::create (
[
"name" => $data['rbranch'],
"company_id" => $company->id
]
);
if(isset($company->id) && isset($branch->id)){
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'phone' => $data['phone'],
'password' => bcrypt($data['password']),
"company_id" => $company->id,
"branch_id" => $branch->id
]);
} else{
return redirect()->back()->withFlashDanger("company or branch no successfully insterted");
}
}

You need to create nullable foreign keys...
In your migration, use the ->nullable() function...
$table->integer('company_id')->unsigned()->nullable();
This will let you not include a company_id initially, the value will be null... without the nullable() the database will not allow null values...
Hope this helps.

Related

Laravel save eloquent model with relations

Sorry if this is something really simple but I haven't been able to find an answer after hours of searching...
I have this object with relations:
$this->versionSelected = new StyleVersions();
$this->versionSelected = StyleVersions::with([
'colourways.colourway_yarns.yarns.spinners',
])->find($id);
Which is edited using wire:model:
wire:model="versionSelected.name"
and then verified:
protected $rules = [
'versionSelected.name' => 'required',
'versionSelected.factories_id' => 'required',
'versionSelected.yarn_transportation_cost' => 'required',
'versionSelected.yarn_transportation_currency' => 'required',
'versionSelected.accessories_cost' => 'required',
'versionSelected.accessories_currency' => 'required',
'versionSelected.transport_cost' => 'required',
'versionSelected.gmt_transportation_currency' => 'required',
'versionSelected.cmt' => 'required',
'versionSelected.gmt_weight' => 'required',
'versionSelected.area_office_commission' => 'required',
'versionSelected.notes' => 'required',
'versionSelected.style_version_prices' => 'required',
];
I then want to save that object to the database, but it is having issues with the relations.
$this->versionSelected->save();
When this is called I get the followin error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'style_version_prices' in 'field list' (SQL: update style_versions set style_version_prices = [{"id":10,"style_versions_id":4,"price":54.7,"notes":"Quo dolorum ab dolores.","created_at":"2022-02-25T10:19:23.000000Z","updated_at":"2022-02-25T10:19:23.000000Z"},{"id":18,"style_versions_id":4,"price":75,"notes":"Voluptatibus aut nihil.","created_at":"2022-02-25T10:19:23.000000Z","updated_at":"2022-02-25T10:19:23.000000Z"},
Is there a way I can update without it looking at the relations, which I can update separately? Thanks in advance! =D
EDIT:
Here is the code for the style_versions table:
Schema::create('style_versions', function (Blueprint $table) {
$table->id();
$table->foreignId('styles_id')->constrained()->onDelete('cascade');
$table->foreignId('factories_id')->constrained()->onDelete('cascade');
$table->text('name')->nullable();
$table->float('yarn_transportation_cost');
$table->float('gmt_weight');
$table->float('cmt');
$table->float('accessories_cost');
$table->float('transport_cost');
$table->text('notes')->nullable();
$table->float('area_office_commission')->default(0);
$table->float('yarn_cost');
$table->text('cmt_currency')->nullable();
$table->text('accessories_currency')->nullable();
$table->text('yarn_transportation_currency')->nullable();
$table->text('gmt_transportation_currency')->nullable();
$table->timestamps();
});
And the model:
class StyleVersions extends Model
{
use HasFactory;
protected $fillable = [
'styles_id',
'factories_id',
'yarn_transportation_cost',
'gmt_weight',
'cmt',
'accessories_cost',
'transport_cost',
'area_office_commission',
'notes',
'cmt_currency',
'accessories_currency',
'yarn_transportation_currency',
'gmt_transportation_currency',
'yarn_cost',
];
public function styles()
{
return $this->belongsTo(Styles::class);
}
public function factories()
{
return $this->belongsTo(Factories::class);
}
public function colourways()
{
return $this->hasMany(Colourways::class);
}
public function style_version_prices()
{
return $this->hasMany(StyleVersionPrices::class);
}
}

Laravel pivot of users_filmscore, ¿How I can check if the user already has scored the film and how to update the relationship attributes?

So, I have a pivot table called user_filmscores, where the users can ''follow (watching, dropped, hold-on...)'' a film and add a rating on it.
In the userController I have this function:
public function userFilm(Request $request){
$data = $request->all();
$validator=Validator::make($data,[
'user_id' => 'required',
'film_id' => 'required',
'state' => 'required',
'score' => 'nullable'
]);
if($validator->fails()){
return response()->json([
'ok' => false,
'error' => $validator->messages(),
]);
}
$film = Film::find($data['film_id']);
$user = User::find($data['user_id']);
$filmId=$data['film_id'];
$userId=$data['user_id'];
//Check if the relationship exists (I tried many methods but always the same result with false)
/*$hasFilm = User::where('id', $data['user_id'])->whereHas('film', function ($q) use ($filmId) {
$q->where('id', $filmId);
})->exists();*/
$hasFilm = $user->film()->where('film_id', '=', $filmId)->exists();
/*$user->film()->sync($film->getKey(), [
'film_id' => $data['film_id'],
'user_id' => $data['user_id'],
'state' => $data['state'],
'score'=> $data['score']
]);*/
if(User::where('id', $userId)->where('id')){
$user->film()->attach($film->getKey(), [
'film_id' => $data['film_id'],
'user_id' => $data['user_id'],
'state' => $data['state'],
'score'=> $data['score']
]);
}else{
$user->film()->detach($film->getKey());
}
}
In the final part of the code, I want to check if the relationship between the user and the film exists, to make an action or another. But when I try to check if the relationship exists, it always returns me a false.
I thought to do it like, if there is a relationship, first delete the old relationship, and then create a new one.
I don't know if there is a better way to do it.
User model has this function:
public function film(){
return $this->belongsToMany('App\Models\Film', 'user_filmscores', 'user_id', 'film_id', 'state', 'score');
}
Film model has this function:
public function user(){
return $this->belongsToMany('App\Models\Film', 'user_filmscores', 'film_id', 'user_id', 'state', 'score');
}
Users table:
Films table:
User_filmscores table:

How to store the request data into 3 different tables?

I have a form that allows an authenticated user create a new conference.
This form will request the user information and some of this information introduced by the user should be stored in the Conference table, some in the "Conference_Category" table and some in the "RegistrationType" table.
So when the user submit the form "dd($request->all());" shows:
array:20 [▼
"_token" => "DbDKu3ryk4NdxKLr3aO132iHrE0O5b0XqfENk1"
"conference_name" => "Conference Name"
"conference_categories" => "1"
"conference_description" => "description"
"conference_creator_name" => "John"
"conference_creator_email" => "email#testemail.email"
"conference_creator_description" => "description"
"registration_type_name" => "registration type name"
"registration_type_description" => "registration type desc"
"registration_type_capacity" => "100"
]
DOUBT
My doubt is how to properly store this request information. Because its necessary to store the request data into 3 different tables to create a new conference:
In the "Conference" table is necessary to store: the conference_name, conference_description, conference_creator_id, conference_creator_name,conference_creator_email, conference_creator_description
In the "conference_category" table is necessary to store: the conference categories id's and the conference id
In the "RegistrationType" table is necessary to store:registration_type_name, registration_type_description and registration_type_capacity
I have a ConferenceController and I have the logic to create a new conference in the store() method of the ConferenceController. But for now I just have the part to store the request information on the Conference table.
Do you know how to also store the categories introduced by the user and the registration type in the respective tables (conference_category and RegistrationType)?
ConferenceController create method:
<?php
namespace App\Http\Controllers;
use App\Category;
use App\Conference;
use Illuminate\Http\Request;
class ConferenceController extends Controller
{
public function store(Request $request)
{
dd($request->all());
$this->validate($request, [
'conference_name' => 'required|max:255',
'conference_categories' => 'required|array|between:1,3',
'conference_startDate' => 'required',
'conference_creator_name' => 'required',
'conference_creator_email' => 'required|email|unique:users',
'conference_creator_description' => '',
'conference_registration_type_name' => 'required',
'confenrece_registration_type_description' => '',
'conference_registration_type_capacity' => 'required',
]);
$conference = Conference::create([
'name' => $request->conference_name,
'description' => $request->conference_description,
'startDate' => $request->conference_startDate,
'conference_creator_id' => Auth::user()->id,
'conference_creator_name' => $request->conference_creator_name,
'conference_creator_email' => $request->conference_creator_email,
'conference_creator_description' => $request->conference_creator_description
]);
}
}
The relationships relevants for this questions are:
Many to many between Conference and Categories (A conference can have many categories, so there is a third table conference_category)
one to many between User and Conference (A user can create many conferences)
one to many between Conference and RegistrationType (A conference can have many registration types)
Conference Model
class Conference extends Model
{
protected $fillable = [
'name', 'description', 'startDate', '...'
];
public function categories(){
return $this->belongsToMany('App\Category');
}
public function conference_creator(){
return $this->belongsTo('App\User', 'conference_creator_id');
}
public function registrationTypes(){
return $this->hasMany('App\RegistrationType', 'conference_id');
}
}
Category Model:
class Category extends Model
{
public function conferences(){
return $this->belongsToMany('App\Conference');
}
}
RegistrationType Model:
class RegistrationType extends Model
{
public function conference(){
return $this->belongsTo('App\Conference');
}
}
User Model:
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password'
];
protected $hidden = [
'password', 'remember_token',
];
public function conferences(){
return $this->hasMany('App\Conference');
}
}
For the Category you want a Many-to-Many relation. Because a Conference can have many Categories and a Category can have many Conferences. You have already set this up correctly in your Models.
After you have created your Conference you can add the categories to the Conference, this can be done using the Attach method(Assuming that the given ids do exist, if not you'll have to check that first):
$conference->categories()->attach($request->conference_categories);
For more information about Attach: Laravel Eloquent
For the RegistrationType, I assume from your Models that a Conference can have multiple RegistrationTypes and a RegistrationType can only have 1 Conference.
You will have to add the following $fillables to your RegistrationType Model:
protected $fillable = ['name', 'description', 'capacity', 'conference_id'];
After you have created your Conference you can create the RegistrationType:
RegistrationType::create([
'conference_id' => $conference->id,
'name' => $request->conference_registration_type_name,
'description' => $request->confenrece_registration_type_description,
'capacity' => $request->conference_registration_type_capacity
]);
End result:
$conference = Conference::create([
'name' => $request->conference_name,
'description' => $request->conference_description,
'startDate' => $request->conference_startDate,
'conference_creator_id' => Auth::user()->id,
'conference_creator_name' => $request->conference_creator_name,
'conference_creator_email' => $request->conference_creator_email,
'conference_creator_description' => $request->conference_creator_description
]);
$conference->categories()->attach($request->conference_categories);
RegistrationType::create([
'conference_id' => $conference->id,
'name' => $request->conference_registration_type_name,
'description' => $request->confenrece_registration_type_description,
'capacity' => $request->conference_registration_type_capacity
]);

How to pass a variable to custom validator

I've created a custom validator that resides in the AppServiceProvider. The boot method contains a DB method that should accept the first patameter passed into the validator as the table name. When I manually fill out the table name, it works but when the first parameter is passed, I run into this error:
QueryException in Connection.php line 729:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'server1.{users}'
doesn't exist (SQL: select count(*) as aggregate from `{users}` where `email` =
mail#mail.com and `STORE_ID` = 2)
Here's my service provider code:
public function boot()
{
Validator::extend('uniqueForStore', function ($attribute, $value, $parameters, $validator) {
$count = DB::table($parameters[0])->where($attribute, $value)->where('STORE_ID', config('constants.STORE_ID'))->count();
return $count === 0;
});
}
This is where the problem lies:
DB::table($parameters[0])
Here's my register user form request code:
public function rules()
{
return [
'first_name' => 'required',
'last_name' => 'required',
'email' => "uniqueForStore:{users}",
'password' => 'required|min:6'
];
}
Set your validation rules as below - just remove brackets for unique value (users):
public function rules()
{
return [
'first_name' => 'required',
'last_name' => 'required',
'email' => "uniqueForStore:users",
'password' => 'required|min:6'
];
}

Laravel 5.3 and Zizaco/entrust : Field 'expired_at' doesn't have a default value

I am using composer Zizaco/entrust and Laravel 5.3's Auth out of the box,
I modified the method create of RegisterController.php like this:
protected function create(array $data)
{
$user =User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
$user->roles()->attach($data['role']);
return $user;
}
The original method create is as follow:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
When I register an user with the modified method,there are 2 problems:
1、There is an error on table role_user:
SQLSTATE[HY000]: General error: 1364 Field 'expired_at' doesn't have a default value (SQL: insert into `role_user` (`role_id`, `user_id`) values (2, 5))
2、Another question is on table users,the field remember_token of table users is null.
It's not at the users table. its on role_user table.
If you have the migration on role_user put nullable on expired_at column should solve it.
Or
You can edit your database.php under config folder. and set strict to false.
For question number 2:
You need to set remember when attempt:
if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// The user is being remembered...
}
for more information about it: https://laravel.com/docs/5.3/authentication#remembering-users
By default remember_token is nullable

Categories