update content of stored column in laravel controller - laravel

I have a table with 3 columns:
firstname
lastname
fullname
in migration:
Schema::create('owners', function (Blueprint $table) {
$table->id();
$table->string('firstname',20);
$table->string('lastname', 20);
$table->string('fullname')->storedAs('CONCAT(firstname,lastname)');
$table->timestamps();
});
the problem is that i want to change the concatenation order in the controller i tried to use db statement but it doesn't work
-in the controller:
$owners= Owner::findOrFail($id);
$owners->update([
'firstname'=>$request['firstname'],
'lastname' =>$request['lastname'],
]);
DB::statement('UPDATE owners SET fullname AS CONCAT(lastname,firstname) STORED WHERE ID=1 ');
I don't want to just use a simple concatenation because the user can change the firstname or the lastname and the order that's why I used storedAs()
any ideas please?

The storedAs method in the migration creates a generated column in mysql. The value is automatically generated from the column values of the firstname and the lastname. There's no way you can change this via an UPDATE statement. You'd have to use an ALTER TABLE statement, which would be horrifically bad practice.
If I were you, I'd keep full name display as a model method so you could access it by using $owner->fullNameFirstLast() or $owner->fullNameLastFirst()

What you should do is create a new migration in order to change the column, the code would be something like this:
Schema::table('owners', function (Blueprint $table) {
$table->string('fullname')->storedAs('CONCAT(lastname,firstname)');
});
This way the column will be changed on a database level, and no need for the controller query you have added

Simply try this
1- update your migration to
Schema::create('owners', function (Blueprint $table) {
$table->id();
$table->string('firstname',20);
$table->string('lastname', 20);
$table->string('fullname', 56);
$table->timestamps();
});
2- in your controller
$owners= Owner::findOrFail($id);
$first_name = $request->firstname ?? $owners->firstname;
$last_name = $request->lastname ?? $owners->lastname;
$full_name = $first_name.' '.$last_name;
$owners->update([
'firstname'=>$first_name,
'lastname' =>$last_name,
'fullname' =>$full_name,
]);
You can also write it this way
DB::statement(DB::raw("UPDATE owners SET firstname = '".$first_name."', lastname = '".$last_name."', fullname = '".$full_name."' WHERE id = $id"));
And the same way for your Create function as well

Related

submit data with the same email in database

How i just want to ask if how can i be able to store another data if i have the same email. i've been making a renting system. after a costumer returned the items, he can be able to send request to rent again. but when i try to submit another form request again. it shows
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'annecurtis#gmail.com' for key 'borrower_requests_email_unique. i already removed the unique() in my the email column on my borrowersRequest table.
how can i do that?
well here is in my controller where costumer submit the data.
public function store(Request $request)
{
$rentform = new BorrowerRequest;
$rentform->user_id = $request->user_id;
$rentform->car_id = $request->car_id;
$rentform->borrowers_name = $request->borrowers_name;
$rentform->email = $request->email;
$rentform->return_date = $request->return_date;
$rentform->contact_number = $request->contact_number;
$rentform->request_status_id = $request->request_status_id;
$rentform->save();
$request->session()->flash('message', 'Your Request has been successfully submitted, please wait for a couple of hours for the approval');
return redirect('/borrowershistory');
anyone pls? thank you. by the way im using laravel and phpmyadmin here.
public function up()
{
Schema::create('borrower_requests', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('car_id');
$table->timestamps();
$table->string('borrowers_name', 50);
$table->string('email');
$table->bigInteger('contact_number');
$table->date('return_date');
$table->unsignedBigInteger('request_status_id')->default(0);
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('car_id')->references('id')->on('cars');
$table->foreign('request_status_id')->references('id')->on('request_statuses');
});
}
Drop the column borrower_requests_email_unique and add it again on the table of database if you don't have useful data now.Then it will be not giving issue.

Laravel 5.5 setting pivot extra fields value?

I'm new to laravel, my problem is i'm trying to set values to extra fields in the pivot table
post_tag
Schema::create('post_tag', function (Blueprint $table) {
$table->increments('id');
$table->uuid('uuid')->unique();
$table->uuid('app_uuid');
$table->uuid('tag_uuid');
$table->uuid('post_uuid');
$table->timestampTz('created_at');
$table->timestampTz('updated_at')->nullable();
});
i want to be ab to set uuid as php function
uuid();
and app_uuid to
$request->app_uuid
one of the ways of adding extra field is to pass data as key-value to attach() method where key is id of a relation field and value is the extra field in pivot table
$post->tags()->attach([$request['id'] => ['uuid ' => uuid()]]);

Eloquent using wrong key for some tables

Using: Laravel 5.5
I Constructing addresses using some address elements (like: district, area, zip etc) as dropdowns & also some user inputs.
I have 5 address element & one of their schema is:
Schema::create('address_districts', function (Blueprint $table) {
$table->increments('id');
$table->integer('admin_id')->unsigned();
$table->string('name');
$table->timestamps();
$table->foreign('admin_id')->references('id')->on('admins');
});
This is for Districts, & I have another 3 exactly same like this called, address_thanas, address_areas, address_building_names & address_zips;
The only exception for the last one is that has code instead of name on other tables:
Schema::create('address_zips', function (Blueprint $table) {
$table->increments('id');
$table->integer('admin_id')->unsigned();
$table->string('code'); // Look other table has name here........
$table->timestamps();
$table->foreign('admin_id')->references('id')->on('admins');
});
I store constructed addresses on the table called addresses
Schema::create('addresses', function (Blueprint $table) {
$table->increments('id');
$table->integer('district_id')->unsigned();
$table->integer('thana_id')->unsigned();
$table->integer('area_id')->unsigned();
$table->integer('zip_id')->unsigned();
$table->integer('building_name_id')->nullable()->unsigned();
$table->string('building');
$table->integer('floor');
$table->string('apt')->nullable();
$table->text('comment')->nullable();
$table->timestamps();
$table->foreign('district_id')->references('id')->on('address_districts');
$table->foreign('thana_id')->references('id')->on('address_thanas');
$table->foreign('area_id')->references('id')->on('address_areas');
$table->foreign('zip_id')->references('id')->on('address_zips');
$table->foreign('building_name_id')->references('id')->on('address_building_names');
});
In Address Model I've defined relationships like:
public function district() {
return $this->belongsTo(AddressDistrict::class, 'district_id');
}
public function thana() {
return $this->belongsTo(AddressThana::class, 'thana_id');
}
public function area() {
return $this->belongsTo(AddressArea::class, 'area_id');
}
public function building_name() {
return $this->belongsTo(AddressBuildingName::class, 'building_name_id');
}
public function zip() {
return $this->belongsTo(AddressZip::class, 'zip_id', 'id');
}
Then when I try to create a new address using Address::create($data)
I get error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name' in 'where clause' (SQL: select count(*) as aggregate from `address_zips` where `name` = 2)
Here we can see that it is comparing the key name instead of id
I noticed that this is not reporting that the data cannot be inserted or something like that, it fails to count related model & for that aborts insertion of data
Why is that?
But the strange thing is I can retrieve data by (inserted a row manually into db for testing to see if that can retrieve data)
$addresses = Address::orderByDesc('created_at')->get();
//loop as $address
$address->district->name
$address->zip->code
...
& this works perfect
When I am creating a new record I need that query look like:
select count(*) as aggregate from `address_zips` where `id` = 2
Any help will be highly appreciated.
Thanks for reading this long question.
The problem is in your $data array. Probably you copied a form with an input name, you need to rename it to code in order to save the values automatically.
Alternatively, you can set the input manually
$address = new Address();
$address->code = request('name');
$address->save();

How to make combination of two columns as a unique key?

I have this table :
public function up()
{
Schema::create('edition', function (Blueprint $table) {
$table->increments('id');
$table->integer('volume');
$table->text('cover')->nullable();
$table->enum('number', ['1', '2']);
$table->timestamps();
});
Schema::table('journal', function(Blueprint $table) {
$table->foreign('id_edition')->references('id')->on('edition')->onDelete('cascade')->onUpdate('cascade');
});
}
I wanted to make the combination of column Volume and Number as a unique key. For example, there is a data "Volume 1, Number 1" and when user insert the same combination it will throw an error message that the data already exist. Is there a way I can do this in Laravel ?
Just include the following snippet inside the up() method
$table->unique(['volume','number']);
By having this constraint set, if you insert 'Volume 1 , Number 1` once it'll be fine. However, if you try to do the same again, it'll throw an error.
Conditions:
You are using some good DBMS, such as MySQL and not SQLITE
You successfully migrated this change into the database.
You can also use uniquewith-validator package that allows you to validate a unique combination of fields like this
'field1' => 'required|unique_with:table_name,field2'
The above code will check if the combination of field1 and field2 is unique in the table with the given table_name.

One to Many relationship in Laravel Eloquent giving undefine method

I am having the said problem when defining one to many relationship with two models, the Student and Enrollment. When accessing the table from another table using:
$enrollment = App\Enrollment::first();
$enrollment->students()->first_name;
Im getting :
Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'students.enrollment_id' in 'where clause' (SQL: select * from `students` where `students`.`enrollment_id` = 1 and `students`.`enrollment_id` is not null)'
However when I use :
$enrollment = App\Enrollment::first();
$enrollment->students()->first_name;
Im getting :
PHP error: Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$first_name on line 1
Can someone help me on this?
Enrollment
protected $fillable = [
'subject_code',
'subject_description',
'section',
'schedule',
'room_no',
'no_of_units'
];
public function students()
{
return $this->hasMany('App\Student');
}
Student
protected $fillable = [
'enrollments_id',
'student_no',
'first_name',
'last_name',
'middle_name',
'birthdate',
'fathers_name',
'mothers_name',
'phone_no',
'degree_id',
'city_id',
'address'
];
public function enrollment()
{
return $this->belongsTo('App\Enrollment');
}
Here's the table for the students and enrollment accordingly
Schema::create('students', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('enrollments_id')->unsigned();
$table->integer('student_no');
$table->foreign('enrollments_id')->references('id')->on('enrollments')->unsigned();
$table->string('first_name');
$table->string('last_name');
$table->string('middle_name');
$table->date('birthdate');
$table->string('fathers_name');
$table->string('mothers_name');
$table->string('phone_no');
$table->string('address');
$table->integer('city_id');
$table->integer('degree_id');
$table->timestamps();
});
Schema::create('enrollments', function (Blueprint $table) {
$table->increments('id');
$table->string('subject_description');
$table->string('subject_code');
$table->time('schedule');
$table->string('room_no');
$table->integer('no_of_units');
$table->string('section');
$table->timestamps();
});
First of all what you exactly want
as per your question i am assuming you want 'enrollment has many students', for this relationship you need enrolment_id in students table not student_id in enrollment table.
and after that use
$students= Enrolment::find(id)->students;
it will return all students with the required enrollment id
That normal since you're trying to get property first_name from hasMany object, you should use get() method if you want to get Collection of objects (in your case collection of students) :
$enrollment->students()->get();
And if you want to get the first name you should specify the object you want to get the first_name from it, e.g :
$enrollment->students()->first()->first_name;
$enrollment->students()->last()->first_name;
If you want to get the attribute first_name of all the students you should use lists method, e.g :
$enrollment->students()->lists('first_name');
Output: collection of all students first names.
Hope this helps.
Update :
Try to remove ->unsigned() in :
$table->increments('id')->unsigned();
and also in :
$table->foreign('enrollments_id')->references('id')->on('enrollments')->unsigned();
When you call relations on an eloquent object it actually return you the relation not the exact objects
for eg: in your case
$enrollment->students() will return the relation
where as
$enrollment->students will return the eloquent object ( in belongs to, has one relations ) and collection/array of eloquent object/objects(in one to many , many to many relations )
simply if you are using it as an attribute you will get the actual result and relation query if it is called as a function
even if you get the relation you can get the results by calling get on top of that
$enrollment->students()->get()

Resources