DataMapper ORM relationships - mysql

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

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

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

Make a users list like instagram

please help..
I have 2 tables
Current user_id = 3
Users Table:
| user_id | email | name |
-------------------------------------------
| 1 | one#gmail.com | ridwan |
| 2 | two#gmail.com | budi |
| 3 | six#gmail.com | stevan |
| 4 | ten#gmail.com | agung |
Relations Table [ user_id and follower_id are related to Users Table ]
| relation_id | user_id | follower_id |
-----------------------------------------
| 1 | 1 | 3 |
| 2 | 2 | 3 |
i want to get the list of the user, but if i already have relation with a user, it will give me a status 'following', just like instagram, maybe look like this
{
user_id : 1,
name : ridwan,
status : following
},
{
user_id : 2,
name : budi,
status : following
},
{
user_id : 4,
name : agung,
status : not following
}
how can i do that in laravel?
thank you..
In your Relations model
public function user()
{
return $this->belongsTo(User::class);
}
Then, in your controller (where you want to get this list), you just need to use Eloquent or Query Builder to get what you want (with eager loading, it's always better) :
//get all users related to your_current_user
$relations = Relation::where('follower_id', your_current_user_id)->with('user')->get();
Finally, you just have to make manipulate your data like you want, for example :
foreach($relations as $relation){
$relation->user->name; //get the name of the related user
}
Take a look at Relationships !
Thank you guys.. finally I use sql case, i was only confusing about how to get the data with 'following' status
here is the code:
DB::table('users')->leftjoin('relationships', 'users.user_id', '=', 'relationships.user_id')->select('users.user_id','users.status as user_type','users.email','users.display_name','users.profile_image',DB::raw('(CASE WHEN relationships.follower_id = ' . $user_id . ' THEN "Following" ELSE "Not Following" END) AS status'))->orderBy('user_id','asc')->where('users.user_id','!=',$user_id)->get();

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?

Relation In Between Models In Yii

I have the database like this
+------------------+
| Invoices |
+------------------+
| id |
| customer_id (Fk) |
| description |
+------------------+
+------------------+
| InvoiceItems |
+------------------+
| id |
| Item_name |
| price |
| discount |
| description |
+------------------+
+------------------+
| Customers |
+------------------+
| id |
| firstname |
| lastname |
| description |
+------------------+
According to the database I made relations in the models as follows.
In Invoices model,the relation is like this
public function relations()
{
return array(
'invoiceitem' => array(self::HAS_MANY,'InvoiceItems','invoice_id'),
'customers' => array(self::BELONGS_TO,'Customer','customer_id'),
);
}
In InvoiceItems model relation is like this
public function relations()
{
return array(
'invoice' => array(self::BELONGS_TO,'Invoices','invoice_id'),
);
}
In Customers model the relations is like this
public function relations()
{
return array(
'invoice' => array(self::HAS_MANY, 'Invoices','customer_id')
);
}
Now I want to know if the relations between these models are right or not?
Your Invoice item does not have a field called invoice_id in the table description. The relations need a reference to the primary key to work. The db-field you declare in the relation should contain the primary key of the model you are working with. So if you are working with a invoice, the HAS_MANY relation should be able to find the id of the invoice in the invoice_id field on the item.
You could also use a separate table for the relation data and declare it like:
array(self::HAS_MANY,'InvoiceItems',reltable('invoice_id', 'item_id))
You can read more about the relations here