CakePHP - Saving One to Many data to database - cakephp-3.0

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

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();

select2 multiple values store in database

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?

DataMapper ORM relationships

table1(users)
|ID|name |type |
|1 |demo |admin |
|2 |demoX |client|
table2(visits)
|ID|admin_id|visitor_id|visit_date|...
|1 |1 |2 |2013-01-01|...
admin(fk)->users(id)
user(fk)->users(id)
simple scheduler project, it contain 2 tables.
1st (users) contain all users, 2nd table contain all bookings(visits).
to get all bookings of an admin i run Select * from visits where admin_id=$id;, and join
visitor info from users table.
........
so basically,
every admin can have many visit
visit must contain (ONE)admin and (ONE)visitor.
how can i setup this kind of relation in datamapper orm ?
This should do it:
class Users extends Datamapper
{
public $has_many = array(
'admin' => array(
'class' => 'users',
'other_field' => 'admin', // FK = admin_id
),
'visitor' => array(
'class' => 'users',
'other_field' => 'visitor', // FK = visitor_id
),
);
}
class Visits extends Datamapper
{
public $has_one = array(
'admin' => array(
'class' => 'users',
'join_self_as' => 'admin', // FK = admin_id
),
'visitor' => array(
'class' => 'users',
'join_self_as' => 'visitor', // FK = visitor_id
),
);
}
// then in your controller you can do:
$visit = new Visitor(1);
echo $visit->admin->name; // echo's 'demo';
echo $visit->visitor->name; // echo's 'demoX';
First of all I think, instead of having a table with admin_id and user_id (isn't helpful), you should have a separate table with users and privileges, then the table structure would be.
Users privileges
| id | user | privilege_id | | id | privilege |
| 1 | user1 | 1 | | 1 | user |
| 2 | admin1 | 2 | | 2 | admin |
Then when you are calling the user level within the application just:
SELECT privilege FROM privileges WHERE id = <privilege_id from users table which should already be set within your code> (MySQL)
you should ALWAYS try and set id's in your tables for this purpose, this will be the basis of your relationship data when your gathering data from another table, so in this example it will be the <id> field of the privileges table and the <privilege_id> of the users table.
From here you should be able to transfer this method across to Datamapper or codeigniter or whatever your misleading tags mean =]
if you need to SELECT a booking from a database, select the booking(make an additional table and append as below) and look for the times of the bookings where ((privilage_id == 1) && (privilage_id == 2)) this will look for the dates where there is both a admin and a user, instead of just looking at one user type you are looking at them all and also saving yourself some hassle by making the call to one column rather than several. also this way you can easily manage your tables as their names relate to there function.
Users privileges booking
| id | user | privilege_id | | id | privilege | | id | date | privilege_id |
| 1 | user1 | 1 | | 1 | user | | 1 |5/2/13| 1 |
| 2 | admin1 | 2 | | 2 | admin | | 2 |5/2/13| 2 |
so the MySQL would be SELECT date FROM booking WHERE ((privilege_id == 1) && (privilege_id == 2)) this will give you the results you would expect, if you need to sanitise your data to go into the tables then you would require two rows to be made in one database which would be done by a procedure like this (this example will use an imaginary filled booking form(and is done in PHP)):
if((isset($user) && (isset($usertype)) && (isset($usertypetwo)) && (isset($date)))
{
if(($usertype != $usertypetwo))
{
"Insert BLAH BLAH"
}
}
also remember using this method you will need to get the user type from the user table to get the privilege_id

Structuring a MySQL database for user information

I am quite new to MySQL, I know most of the basic functions and how to send queries etc. However, I am trying to learn about structuring it for optimal searches for user information and wanted to get some ideas.
Right now I just have one table (for functionality purposes and testing) called user_info which holds the users information and another table that stores photos linked to the user. Ideally id like most of this information to be as quickly as accessible as possible
In creating a database which is primarily used to store and retrieve user information (name, age, phone, messages, etc.) would it be a good idea to create a NEW TABLE for each new user that stores all the information so the one table user_info does not become bogged down by multiple queries, locking, etc. So for example user john smith would have his very own table in the database holding all his information including photos, messages etc.
OR
is it better to have just a few tables such as user_info, user_photos, user_messages,etc. and accessing data in this manner.
I am not concerned about redundancy in the tables such as the users email address being repeated multiple times.
The latter is the best way. You declare one table for users, and several columns with the data you want.
Now if you want users to have photos, you'd require a new table with photos and a Foreign Key attribute that links to the user table's Primary Key.
You should definitely NOT create a new table for each user. Create one table for user_info, one for photos if each user can have many photos. A messages table would probably contain two user_id columns (user_to, user_from) and a message column. Try to normalize the data as much as possible.
Users
====
id
email
etc
Photos
====
id
user_id
meta_data
etc
Messages
====
id
user_id_to
user_id_from
message
timestamp
etc
I agree with both the answers supplied here, but one thing they haven't mentioned yet is lookup tables.
Going with the general examples here consider this: you have a users table, and a photos table. Now you want to introduce a featre on your site that allows users to "Favorite" photos from other users.
Rather than making a new table called "Favorites" and adding in all your data about the image (fiel location, metadata, score/whatever) all over again, have a table that effectively sits BETWEEN the other two.
+-----------------------+ +-------------------------------------+
| ++ users | | ++ photos |
| userID | email | name | | photoID | ownerID | fileLo | etc... |
+--------+-------+------| +---------+---------+--------+--------+
| 1 | .... | Tom | | 35 | 1 | ..... | .......|
| 2 | .... | Rob | | 36 | 2 | ..... | .......|
| 3 | .... | Dan | | 37 | 1 | ..... | .......|
+--------+-------+------+ | 43 | 3 | ..... | .......|
| 48 | 2 | ..... | .......|
| 49 | 3 | ..... | .......|
| 53 | 2 | ..... | .......|
+---------+---------+--------+--------+
+------------------+
| ++ Favs |
| userID | photoID |
+--------+---------+
| 1 | 37 |
| 1 | 48 |
| 2 | 37 |
+--------+---------+
With this approach, you link the data you have cleanly, efficiently and without too much data replication.

Set up Table to store variable number of fields per record?

How should I set up my database / table, if I do not know the number of fields I would populate per record?
For example, if I have a web form that allows a user to enter all the cars he owns, and I don't want to limit him to a certain number, how would I store this in the database end?
The above problem extends to similar situations such as storing a user's order (variable number of items per order) etc.
In Relational Database Management Systems (RDBMS) instead you create child records in a dependent table that relate child entities (cars) with parent entities (users). There is a concept known as database normalization, and the objective is that each table contains data for a single type of entity.
So you have a user table with the user information:
user_id | user_name | email | ...
1234 | User1 | user1#example.com | ...
2356 | User2 | user2#example.com | ...
Then another table for storing the information of each car of a user:
user_car_id | user_id | car_label | make | model | ...
1 | 1234 | MyCar | Ford | 2011 | ...
2 | 2356 | A Car | Chevrolet | 2010 | ...
3 | 1234 | MyOtherCar| BMW | 2000 | ...
So instead of storing the info of the cars in the user table, you have a table for storing car (user_car) information related to each user by way of the user_id column. This is an example of a one-to-many relationship, in which one user can have many related cars.
this is an entire topic: database normalization.
the short answer is you make more than one table.
in your example you would have person table, a car table, and a third that linked person to the car