select2 multiple values store in database - mysql

I have successfully made a searchable drop down list,in which whenever I type something, data from database appears in drop down list, now I want to store these multiple values which are selected, in the database.
My code in controller
$temp = $model->package_item = $_POST['package_item'];
foreach($temp as $t)
{
$model->package_item=$t;
}
Package_item is the field in which searchable dropdown list is applied, and I am selecting multiple values, now how can I save these values in the database, so that I will have a single id, but against this id, package_item will have multiple values and the rest of the attributes will be repeated. Just like below.
id------package_item------package_description------package_name
1--------cake------------ very cheap-------------get one buy one free
1---------candles---------- very cheap-------------get one buy one free
1----------fireworks--------very cheap-------------get one buy one free
I am using select2 extension and here is the code for that in view file
$this->widget('ext.select2.ESelect2', array(
'name' => 'package_item',
'data' => CHtml::listData(Package::model()->findAll(), 'id', 'package_item'), //the whole available list
'htmlOptions' => array(
'placeholder' => ' search packge item?',
//'options' => $options, //the selected values
'multiple' => 'multiple',
'style'=>'width:530px',
),
));
Thanks in advance

My first answer was terribly misleading, so I deleted it and here and giving it another try.
You need to plan out your database tables. I'm making a suggestion here:
Table Items
itemId[PK]| name | price |...|
1 | cake | 5.00
2 | candles | 2.00
3 | fireworks | 10.00
4 | expensiveStuff | 50.00
Table Packages
packageId[PK] | name | description | price |
1 | full package | super cheap | 12.00
2 | epic package | best value for money | 55.00
Table PackagesItems
packageId[PK][FK]|itemId[PK][FK]|amount
1 | 1 | 1
1 | 2 | 1
1 | 3 | 1
2 | 1 | 2
2 | 2 | 2
2 | 3 | 3
2 | 4 | 1
You would then query your packages like this:
SELECT itemId FROM PackagesItems WHERE packageId = 1 for example
The keyword of this answer is COMPOSITE PRIMARY KEY, which you can see in the third table: there are two primary keys, which are also foreign keys that lead to the other tables.
With SQL JOINS, you could retrieve the information from the other two tables.
If you need more information, please narrow down the scope of your question. What exactly do you want to know?

Related

Is it possible to insert records if not exists and delete records if not provided in Laravel and MySQL?

I have couple of checkboxes in my Laravel View lets say:
<input type="check" name="John">
<input type="check" name="Jane">
<input type="check" name="Mae">
<input type="check" name="Peter">
When I check all of the checkboxes, It will be save in the database like so:
#Participants Table
_____________
id | name
----+--------
1 | John
2 | jane
3 | Mae
4 | Peter
In my Log table:
#Log Table
_________________
id | activity
----+------------
1 | Added John as participant
2 | Added jane as participant
3 | Added Mae as participant
4 | Added Peter as participant
Now, my problem is when updating the participants.; In my Laravel view, I have all my checkbox selected based on the participants table data and let's say I unchecked John and Peter, When click update How can I add a history in my Log table that will display like this:
#Log Table
_________________
id | activity
----+------------
1 | Added John as participant
2 | Added jane as participant
3 | Added Mae as participant
4 | Added Peter as participant
5 | Removed John as participant
6 | Removed Peter as participant
and then in my Participants Table
#Participants Table
_____________
id | name
----+--------
2 | jane
3 | Mae
What I have done so far on Update:
$members = json_decode($request->projectmembers);
foreach ($members as $participantsitems) {
DB::beginTransaction();
DB::table('projects_participants')->upsert([
'project_id' => $request->projectid,
'task_id' => "",
'emp_number' => $participantsitems->id,
'created_by' => Auth::user()->emp_number,
'date_created' => Carbon::parse(Carbon::now()),
],
[
'project_id' => $request->projectid,
'emp_number' => $participantsitems->id,
]);
DB::commit();
$this->record_project_history("Added ".$participantsitems->name ." as participant",$request->projectid, "");
}
But what it did was insert if record does not exists and update if record exists. can anyone give me an Idea on how to solve my problem? Thank you!
There's no direct why to do that.
you should do this logic yourself.
But you there're some staff could help you (append to you method this snippet):
// after update/insert your new data you will need to delete other records
// using updated_at column to delete all records updated a second ago
// make sure to create a model for projects_participants and use it all over your code
ProjectsParticipant::where('project_id', $request->projectid)
->where('updated_at', '<=', Carbon::now()->subSecond())->delete();

Laravel get "unique" row from mysql

I have a special scenario to fetch "unique" row.
Let's say the database is like below
| id | userid | value | others |
|----|--------|-------|---------|
| 1 | 111 | 10 | string1 |
| 2 | 112 | 30 | string2 |
| 3 | 112 | 30 | string3 |
| 4 | 113 | 50 | string4 |
what I want to achieve is to fetch the unique rows based on the "userid" so I'am able to sum all values.
the expect output row can be either id: 1 2 4 or 1 3 4 (both is acceptable for this special case because same id guarantees same value, or in general, get just one row from those row with same userid. ), so the sum will be 90.
Note: DB is extended from Eloquent\model
My old approach is to get DB::unique('userid'); then for each userid DB::where('userid', $id)->value('value'), add the result to sum; I just believe there might be a better approach.
There is Illuminate\Support\Facades\DB in Laravel, it can return the Query Builder. Not recommend to use a model that is named DB.
So just change another name.
By the way, for Eloquent\Model, you can use groupBy and sum too:
Model::groupBy('user_id')->sum('value');

CakePHP - Saving One to Many data to database

I'm having a problem saving the data to the database. I can't seem to figure how one-to-many works. So heres the scenario: One journal voucher has many entries in it (debits and credits).
Vouchers Table
| voucher_id(pk) | voucherNo | notes | amount | date |
Entries Table
| entry_id(pk) | voucher_id(fk) accountname | description | debit | credit |
EntriesTable
$this->belongsTo('Vouchers', [
'foreignKey' => 'voucher_id',
'joinType' => 'INNER'
]);
From the vouchers's side you should be fine as described in the cookbook:
https://book.cakephp.org/3.0/en/orm/saving-data.html#saving-hasmany-associations
From the entries side is not the normal way, but you can do it also:
https://book.cakephp.org/3.0/en/orm/saving-data.html#saving-belongsto-associations

how can we add two field in same column in sql table?

i want to create a database that consists all products rating and notes purchase by user
suppose that i create a table name "Users_rating_product" that consists some column
user_id ->INT
company->Varchar
product1 -> 3 (rating of product out of 5)|(review of product)
product2-> 4(rating)|(some review)
i want to know how can i do it in mysql . i'm using phpmyadmin for database creation
table looks like
user_id | company |Ac | TV | fridge
1 | goderaj |3 ,take more power |4,less power |5,efficient
i want to know how can i do this so that both rating and notes for product display in same column
For this you'll need a separate table. Call it ProductRating. Put a unique key (ID) to the table and reference that key to your Users_rating_product table.
For example:
Users_rating_product:
user_id | company |Ac | TV | fridge
1 | goderaj |1 | 2 | 3
2 | somecomp |4 | 5 | 6
ProductRating
ID | Rating | Review
1 | 3 | Take more power
2 | 4 | less power
3 | 5 | efficient
4 | 5 | excellent
5 | 1 | awful
6 | 3 | average
There are many ways that you can achieve your functionality.
but this is not standard format to write queries.
you can have comma seperated column in your database like this
user_id | company |Ac_mapping_id
1 | goderaj |1,REview for Ac
for Seperate two values you can do like this
PARSENAME(REPLACE(String,',','.'),2) 'Name'
for Detail Reference for splitting two values you can refer :
click To refer
Better Way is to store Product description in different table.
You can easily write queries to retrieve your data
user_id | company |Ac_mapping_id | TV_mapping_id | fridge_mapping_id
1 | goderaj |1 | 2 | 3
& store all the ratings & reviews in mapping table like this
Ac_mapping_id | Rating |Review
1 | 1 |abcd
So on for the other table.
For Retrieving all the data just Use Left outer join
Select
*
from
Users_rating_product mm
Left outer join Ac_mapping_table ac on ac.ac_mapping_id = mm.ac_mapping_id
.....so on

How to store multiple values in single column where use less memory?

I have a table of users where 1 column stores user's "roles".
We can assign multiple roles to particular user.
Then I want to store role IDs in the "roles" column.
But how can I store multiple values into a single column to save memory in a way that is easy to use? For example, storing using a comma-delimited field is not easy and uses memory.
Any ideas?
If a user can have multiple roles, it is probably better to have a user_role table that stores this information. It is normalised, and will be much easier to query.
A table like:
user_id | role
--------+-----------------
1 | Admin
2 | User
2 | Admin
3 | User
3 | Author
Will allow you to query for all users with a particular role, such as SELECT user_id, user.name FROM user_role JOIN user WHERE role='Admin' rather than having to use string parsing to get details out of a column.
Amongst other things this will be faster, as you can index the columns properly and will take marginally more space than any solution that puts multiple values into a single column - which is antithetical to what relational databases are designed for.
The reason this shouldn't be stored is that it is inefficient, for the reason DCoder states on the comment to this answer. To check if a user has a role, every row of the user table will need to be scanned, and then the "roles" column will have to be scanned using string matching - regardless of how this action is exposed, the RMDBS will need to perform string operations to parse the content. These are very expensive operations, and not at all good database design.
If you need to have a single column, I would strongly suggest that you no longer have a technical problem, but a people management one. Adding additional tables to an existing database that is under development, should not be difficult. If this isn't something you are authorised to do, explain to why the extra table is needed to the right person - because munging multiple values into a single column is a bad, bad idea.
You can also use bitwise logic with MySQL. role_id must be in BASE 2 (0, 1, 2, 4, 8, 16, 32...)
role_id | label
--------+-----------------
1 | Admin
2 | User
4 | Author
user_id | name | role
--------+-----------------
1 | John | 1
2 | Steve | 3
3 | Jack | 6
Bitwise logic allows you to select all user roles
SELECT * FROM users WHERE role & 1
-- returns all Admin users
SELECT * FROM users WHERE role & 5
-- returns all users who are admin or Author because 5 = 1 + 4
SELECT * FROM users WHERE role & 6
-- returns all users who are User or Author because 6 = 2 + 4
From your question what I got,
Suppose, you have to table. one is "meal" table and another one is "combo_meal" table. Now I think you want to store multiple meal_id inside one combo_meal_id without separating coma[,]. And you said that it'll make your DB to more standard.
If I not getting wrong from your question then please read carefully my suggestion bellow. It may be help you.
First think is your concept is right. Definitely it'll give you more standard DB.
For this you have to create one more table [ example table: combo_meal_relation ] for referencing those two table data. May be one visible example will clear it.
meal table
+------+--------+-----------+---------+
| id | name | serving | price |
+------+--------+-----------+---------+
| 1 | soup1 | 2 person | 12.50 |
+------+--------+-----------+---------+
| 2 | soup2 | 2 person | 15.50 |
+------+--------+-----------+---------+
| 3 | soup3 | 2 person | 23.00 |
+------+--------+-----------+---------+
| 4 | drink1 | 2 person | 4.50 |
+------+--------+-----------+---------+
| 5 | drink2 | 2 person | 3.50 |
+------+--------+-----------+---------+
| 6 | drink3 | 2 person | 5.50 |
+------+--------+-----------+---------+
| 7 | frui1 | 2 person | 3.00 |
+------+--------+-----------+---------+
| 8 | fruit2 | 2 person | 3.50 |
+------+--------+-----------+---------+
| 9 | fruit3 | 2 person | 4.50 |
+------+--------+-----------+---------+
combo_meal table
+------+--------------+-----------+
| id | combo_name | serving |
+------+--------------+-----------+
| 1 | combo1 | 2 person |
+------+--------------+-----------+
| 2 | combo2 | 2 person |
+------+--------------+-----------+
| 4 | combo3 | 2 person |
+------+--------------+-----------+
combo_meal_relation
+------+--------------+-----------+
| id | combo_meal_id| meal_id |
+------+--------------+-----------+
| 1 | 1 | 1 |
+------+--------------+-----------+
| 2 | 1 | 2 |
+------+--------------+-----------+
| 3 | 1 | 3 |
+------+--------------+-----------+
| 4 | 2 | 4 |
+------+--------------+-----------+
| 5 | 2 | 2 |
+------+--------------+-----------+
| 6 | 2 | 7 |
+------+--------------+-----------+
When you search inside table then it'll generate faster result.
search query:
SELECT m.*
FROM combo_meal cm
JOIN meal m
ON m.id = cm.meal_id
WHERE cm.combo_id = 1
Hopefully you understand :)
You could do something like this
INSERT INTO table (id, roles) VALUES ('', '2,3,4');
Then to find it use FIND_IN_SET
As you might already know, storing multiple values in a cell goes against 1NF form. If youre fine with that, using a json column type is a great way and has good methods to query properly.
SELECT * FROM table_name
WHERE JSON_CONTAINS(column_name, '"value 2"', '$')
Will return any entry with json data like
[
"value",
"value 2",
"value 3"
]
Youre using json, so remember, youre query performance will go down the drain.