how to name database column appropriately - mysql

In excel file, I have columns like this; 11.01-12.00, 12.01-13.00, ..., 29.01-30.00. And the content of the column is the price. I want to store a price in many ranges in MySQL like excel column.
Do I have to create a table like this or Do your guys have any better way please guide me?

An option may be to define a column price_range or prices as json column and store the data as key=>value pairs for eg: '11.01-12:00'=> 11.50
In your migration file for the table, add a column
$table->json('prices');
And in your model class, specify to cast prices column as array.
class MyModel extends Model
{
protected $casts = ['prices' => 'array'];
//... rest of the class code
}
By specifying the cast, you can now use associative array to store data on the column, you can work in php arrays to store and update data.
$myModel = new MyModel;
$myModel->prices = [
'11.01-12.00' => 11.50,
'12.01-13.00' => 12.35,
//...
'29.01-30.00' => 29.82,
];
$myModel->save();
To update data
$myModel = MyModel::find(5);
$newPrices = [
'11.01-12.00' => 11.20,
'12.01-13.00' => 12.63,
//...
'29.01-30.00' => 29.05,
]
$myModel->update(['prices' => $newPrices]);
/OR to update price for a specific price range
$myModel->update(['prices->11.01-12.00' => 11.25]);
Laravel docs:
https://laravel.com/docs/8.x/eloquent-mutators#array-and-json-casting
https://laravel.com/docs/8.x/eloquent#mass-assignment-json-columns
https://laravel.com/docs/8.x/queries#updating-json-columns

In your database table migration file, define a column called price to hold your value.
$table->integer('price');
Store your price as the lowest denominator for your currency performing whatever arithmetic is required to perform the conversions in/out of the database.
There is no need for you to create individual columns for different prices.
Edit 1
Based on your question update that the information is in an excel file, you'll want to make use of a package such as Laravel Excel (no point reinventing the wheel) to perform your import.
Nice tutorial for importing an excel file here

Related

Laravel Many To Many Merges Pivot?

I must be going insane or be really tired. So I have this situation where I get a collection of all the Roles assigned to the User. That part goes ok.... however I noticed something super strange.
I am using Laravel 8 and PHP8 (not the strange part).
For some reason, I do not get only the result from the other table but also pivot data is merged in. I can't tell why this is happening. Here is the example:
Relationship on user model:
/**
* Relationship with roles model.
*
* #return BelongsToMany
*/
public function roles(): BelongsToMany
{
return $this->belongsToMany(
Role::class,
'role_user',
'user_id',
'role_id'
)->withTimestamps();
}
Relationship on the Role model:
/**
* Relationship with users table.
*
* #return BelongsToMany
*/
public function users(): BelongsToMany
{
return $this->belongsToMany(
User::class,
'role_user',
'role_id',
'user_id'
)->withTimestamps();
}
In the user model, I have this.
$this->roles->each(function($role) {
dd($role);
});
I was expecting to get a dump of related model however for some weird reason what I get is pivot table merged with the model:
"id" => 7 // this is the relation ID from the pivot table
"display_name" => "Administrator" // this is from Role model
"code" => "admin" // role model
"description" => "Super User - can do everything in the system. This role should only be assigned to IT staff member." // role model
"created_at" => "2021-10-01 11:00:00" // pivot table
"updated_at" => null // pivot table
"deleted_at" => null // pivot table
"role_id" => 1 // pivot table
"user_id" => 2 // pivot table
Either I am doing something very wrong or I am missing something very obvious. Does anyone know what in the world is happening here?
Just to add: the data is from both places but the result is just a Role model as expected.
Should I not just get the role model without the pivot stuff in it? It is overriding my role model fields.
EDIT:
Parenthesis seems to make a difference. The data is still merged. However, when I do it like this looks like data from end model is merged (so it overrides) to data from the pivot. So I get correct ID.
$this->roles()->each(function($role) {
echo $role;
});
But this gives me this weird pivot merged version with wrong ID.
$this->roles->each(function($role) {
echo $role;
});
I know what that was exactly. Without thinking I've added the ID column into the pivot table.
This ID from pivot was overriding my ID from my end model. After I've removed it the problem is gone.
I don't know why Laravel would by default add these fields and merge with pivot columns... I guess it just does that for no reason. Although I don't understand what's the point if there is a separate mechanism to access the pivot table (pivot relationship on the model).
This makes me think I did something wrong. But yeah, hope it helps. If anyone knows why Laravel automatically adds pivot stuff, let me know.

MySql Update Query to insert JSON values

In MySql I have two tables: staff and certifications. There is a one-to-many relationship where staff.pk = certifications.fk.
For each staff member, I need to insert their multiple certifications.name values into a JSON column in the staff table.
I also need to be able to read this as an array cast in a Laravel - does that mean it needs to be a JSON array, rather than a JSON object?
UPDATE:
I need to do this as a batch process, since I have many thousands of records to process. That's why I am concencentrating on the raw SQL. Instantiating Eloquent models would not work from a performance perspective.
you can use Accessors & Mutators
namespace App;
use Illuminate\Database\Eloquent\Model;
class Staff extends Model
{
//assuming you have certificates column in staff table to store json data
public function setCertificatesAttribute($certificates)
{
$this->attributes['certificates'] = json_encode($certificates);
}
public function getCertificatesAttribute()
{
if($certificates != null){
return json_decode($certificates, true); //force to array
}
return []; //default empty array
}
}
Now if you create or update staff
Staff::create([
'name' => 'Staff1',
'certificates' => ['certificate1', 'certificate2']
]);
Then it will automatically saved as a json data in your staff table. And when you fetch data using $staff->certificates then it will return you array.
hope it may solve your problem

Yii2 - Checkboxlist Value Store In Database

in my db structure
service_request type enum('towel','tissue','napkin')
then have a model
* #property string $service_request
then in my view
<?= $form->field($model, 'service_request')->checkBoxList([ 'towel' => 'Towel', 'tissue' => 'Tissue', 'napkin' => 'Napkin']) ?>
then when i choose towel, tissue and napkin then submit the form, it's have an error said
Service Request must be String
please help me
Thank You
Like Joji Thomas said, checkBoxList prodices an array.
You need to change your database structure so that it supports 1-to-many relations (each $model can have multiple service_requests) if you want to save this. Unfortunately Yii is not very good at this sort of thing out of the box so you have to do a bunch of things yourself.
First you need to create a ServiceRequest ActiveRecord.
Then your $model needs to have a relation like:
public function getServiceRequests() {
return $this->hasMany(ServiceRequest::className(), ['model_id' => 'id'];
}
Then in your controller (model create action) you will need to do something like this:
foreach (Yii::$app->request->post('ServiceRequest',[]) as $data) {
$item = new ServiceRequest($data);
$model->link('serviceRequests', $item);
}
If you wanna update the checkboxes too then you need to do something similar in your model update action as well.
Please change checkBoxList to radioList, because when selecting multiple values service_request becomes an array. Enum type can handle only string values.
First change your filed datatype from enum to varchar. enum only takes a single string value.
Secondly you need to implode service_request array to string for save to db.
Use bellow code before the model save function :
$model->service_request = implode("," , $model->service_request);
$model->save();

laravel5-How can i hide the specific column of withPivot?

I use belongstomany function to get the models and used withPivot() to get an extra column data in the pivot table. However, the withPivot() function will add the 2 foreign keys in the output json. I want to hide thses keys and only show the column I want to display.
The follwing is my response data
{"status_code":"1","next_page":"2","dataset":[{"id":"829","req_start_time":"2016-03-13 14:55:00","req_end_time":"2016-03-13 09:55:00","content":[{"name":"\u9752\u6912\u7092\u725b\u8089","price":"120","pic_url":"","detail":"\u8d85\u7ea7\u597d\u5403\u7684\u54df","pivot":{"waiter_request_id":"829","goods_id":"2","count":"2"}}
as you see the pivot json object contains two id keys.
how could i remove them from the object? or some other ways to solve this get the right way of this need?
thx in advance!
Now the question already upgraded!
How can I add this 'count' parameter of pivot in the object which belongs to 'content'
Finally,I figured out the right way to solve this problem. Follwing the code:
class Goods extends Model{
......
......
public function newPivot(Model $parent, array $attributes, $table, $exists)
{
$pivot = new Pivot($parent, $attributes, $table, $exists);
$pivot->addHidden(
array(
'waiter_request_id',
'goods_id'
)
);
return $pivot;
}
}
you can rewrite this method to provide a new pivot object to the Model in your 'belongsToMany'

how to store instance methods name of a class in a column in sql database?

I want to create a column that has nested hash structure.
structure of that column:
column_name: company
{ production=> {watch=> "yes",pen =>"no",pencil => "yes"}
quality => {life_test =>"yes", strong_test =>"yes", flexibility_test => "no"}
}
Here production, quality are my models and watch, pen, pencil, life_test,strong_test are my instance method of respective classes. each instance method will get the Boolean value from the view page.
How to achieve this structure.
This is called serialization and it is pretty easy. You could do the following:
class Something < ActiveRecord::Base
serialize :company, JSON
end
bar = Something.new
bar.company = { :production=> {:watch=> true,:pen => false, :pencil => false}
:quality => {:life_test =>true, :strong_test =>true, :flexibility_test => false} }
bar.save
If you want more info go here: http://api.rubyonrails.org/classes/ActiveRecord/Base.html and read the part on "Saving arrays, hashes, and other non-mappable objects in text columns" just make sure your company column in the database is a text column.
Use serialization to store hash in db .
Follow api link