Saving a HasMany relationship data with a compound index in CakePHP - php

I'm currently using CakePHP 2.x.
I make all my forms using the form_helper and then the active record way to save the model data. It's really tidy and simple, but I can't find the way to save one particular structure.
I've 2 tables, one for the user basic information and one for the user details, with a lot of different fields: User and User_Detail.
User:
id | name | email
------------------------
1 | John | john#doe.com
2 | Paul | paul#doe.com
User_Detail:
id | user_id | field | value
-----------------------------
1 | 1 | sex | m
2 | 1 | age | 21
3 | 2 | height | 180
What's the best way to make the user fill some fields? What fields to complete can be hardcoded in the app. Is it possible using a form helper and saveRelationship()?

Based on your comments, I would add a new table that contains the name of the "custom fields", lets call it "custom_fields" and this would be its definition
custom_fields:
id
name
Its model is called CustomField and it hasMany UserDetail
Your user_details table will have this structure
user_details:
id
user_id
custom_field_id
value
This model (UserDetail) belongsTo CustomField.
Your model User hasMany UserDetail.
Now, in your users form you might want to have a select with all possible CustomValues, in order to do this you previously did something like this in your controller
$customValues = $this->CustomValues->find('list');
$this->set(compact('customValues'));
So, in your view you will have something like this
echo $this->Form->input('UserDetail.custom_field_id', array('type' => 'select', 'values' => $customValues));
echo $this->Form->input('UserDetail.value')
And of course, after submitting this form you will call Model::SaveAssociated
I hope you have now the idea.

Assuming that I understand what your trying to do ..... If using Form Helper you can construct your input fields as follows:
echo $this->Form->input('User.name');
echo $this->Form->input('User.email');
echo $this->Form->input('User_Detail.sex');
echo $this->Form->input('User_Detail.age');
echo $this->Form->input('User_Detail.height');
Then when you save you should use saveAssociated($this->request-data) and it should work by saving the record into both models and automatically creating the appropriate User_Detail.user_id field.

Related

Unique input fields based on specific event type ID's

I've been tasked with creating a physical event logging system, where an employee will create an event based on a physical event that occurred purely for logging purposes. For example, say they answer the phone - they must then create a "Phone" event and fill in who called, why, and when.
Each event will have the same input fields accessible to enter, however some of them require additional input fields that are only accessible to specific event_types.
Here's a snippet of the schema:
table: event_types
| column | type |
|--------|---------|
| id | integer |
| name | varchar |
table: events
| column | type |
|---------------|----------|
| id | integer |
| report_id | integer |
| user_id | integer |
| event_type_id | integer |
| date | datetime |
| details | text |
| locations | json |
| people | json |
| data | json |
Basically, the event_type_id can be one of 50+ event types. Only 15 of them will require unique fields. These event types are static when the app is installed (they are seeded into the DB), and users won't be creating them in the app itself.
The locations, people and date field will be available inputs on every event. My initial thoughts was to have a data json field to store additional input field data.
However, I'm not sure if this is the best way to handle unique input fields depending on specific event_type_id's. I'm also not sure how I'll handle validating these unique fields based on the event_type_id.
Would it be best to hard-code event_type_id's and then assign validation rules depending on which event_type_id an event is created with? I'm also wondering how to handle this when rendering the form view to load in the additional input fields.
I've also thought about storing the validation rules and the view name inside the event_types table, but I thought doing so may be bad practice since I'd need to update the event_type record in the database anytime I want to add another field.
I'm really hoping for some advice from anyone who's had to implement handling unique fields within their database - I'm really not sure how to handle this properly... Thanks so much for your time!
EDIT: I've went with a hybrid - a very limited version of the Entity-Value-Model and json data fields. I'll be posting my complete implementation in the coming days for others in case it helps anyone.

Create auto generated forms for each new table

I use yii2 framework in my application and I have a table named objects in my SQL database
"objects" ( object_id , object_typeID , ... )
But we have some objects that have special fields and user should be able to add custom fields to objects form
My solution is create a new table named object-type-"index" for each new objects that have custom fields!
But how should I automatically create custom form for each object-type-"index" tables? Can I use gii module to generate automatic forms?
For custom fields you should have two additional tables for all "objects":
[object_field_value]
object_id | field_id | value
2 | 5 | Yes
2 | 6 | Blue
3 | 5 | No
[object_field]
ID | name | [other attributes for field]
5 | Colorful? |
6 | Base color |
That way you can match object with it's all fields

After adding meta_box, how allow admin user to create multiple ones (i.e. create array of that type)? Like adding new custom fields of the same name

I have created a function that is called on the hook add_meta_boxes which creates a new meta type employee (this is just an testing example) which shows inputs for name, department and picture. But I don't want to add just one, I want to also have a button for the admin user to create another employee, so that on the page, in the loop, I can get an array of the meta_key employee.
Is the only way to do this, to insert a script and button, so that on button press, the JavaScript creates all the inputs via the DOM? Or is there a "Wordpress-Official" api/function for doing this?
I want something like:
-------------------------------------------------------------------
| Employee |
-------------------------------------------------------------------
| Name: ____________________ |
| Department: ____________________ |
| Picture: browse... |
| -------- |
| | Save | |
| -------- |
-------------------------------------------------------------------
------------------------
| Add Another Employee |
------------------------
A "cleaner" way to do this, would be to create a number of custom post types, and link them using Posts 2 Posts [1] - then you can do nicer things.
Meta is an easy way to do stuff, but I find you eventually end up regretting the choice to do it that way.
[1] http://wordpress.org/plugins/posts-to-posts/

Different user types with different data

I've got a project, to build a model agency cms.
The back end and other parts are okay for me, what I am inexperienced with is the different users, and I am stuck with the logic.
My logic would be this
Create a groups table with the following names and levels
id | group_id | level
1 | Admin | 20
2 | Moderator | 10
3 | Model | 1
4 | Photographer | 1
5 | Stylist | 1
6 | Agency | 1
the group id and user id would be saved in an users groups table like this
group_id | user_id
1 | 1
1 | 5
1 | 6
3 | 10
And here comes what I am stuck with it, so since these users have different data, I was thinking to create multiple forms for them with some fields hidden what is not needed for the actual user type, and when someone browses the profile, a switch chase would be made for the group check, and show different profiles
example
switch ($user->groupId) {
case 3:
// model profile
break;
case 4:
// photographer profile
break;
// and others
}
Is it a good logic in a way? Could somebody show me some examples or give me a hint?
Thank you
Edit
I am not using framework, i have made my own basic cms based on propel
IMO the best way to achieve this is to try using Single Table Inheritance or Concrete Table Inheritance in Propel. You can read about it here http://propelorm.org/Propel/documentation/09-inheritance.html

Yii: Find in Active Record by a PHP Expression

Say you have an Active Record model which contains a set of records:
id | name
---------
1 | Record1
2 | Record2
3 | Record3
Users who has the permission to see each records are stored in another table, using a foreign key to represent the record, in a comma separated way:
foreignId | users
-----------------
1 | joe, doe, zoe
2 | joe
3 | doe, zoe
There is an authentication manager bizRule which checks if current user has the permission to see a record. You give it the record id and it checks the permissions table to see if the user is in the comma separeted field.
Yii::app()->authManager->checkAccess('seeRecord', $id);
Is there an easy way using CActiveRecord to pass a PHP Expression "query"? Something like:
Record::model()->findByPHPExpression('Yii::app()->authManager->checkAccess('seeRecord', array('id' => 'id'));
If the expression returns true for the current record, that record would be added.
Thank you
You have some serious non-yii related issue, your database schema is wrong, please read some about database normalization.
You should have an intermediate table, if a user can see various records, and a record can be seen by various users, then you need an intermediate table.
Users, Users_cansee_Records, Records
The intremediate table will have 2 primary keys, that are the user_id and record_id respectively
for your example this table will have something like:
user | record
--------------
1 | joe
1 | doe
1 | zoe
2 | joe
3 | doe
3 | zoe
Yii supprots this "Many many" relationships out of the box. but please read about database normalization, its an important topic, database design is a critical step in any project development.

Categories