Using ActiveRecord to achieve complex relations in Rails - mysql

From another question of mine:
What I need to achieve is this: Create multiple categories with their
own designated information fields (ie. Cars have different fields from
Pets) and once such a category is created, the commands I need will be
invoked and a new table for each category will be made. I know I could
store all fields as some sort of string and then process it to display
it properly, but I need a advanced search function for my web app and
creating separate tables for each category seems the best way to
achieve it. I would really like to hear alternatives for this
So I have this situation where I need categories to hold all input fields needed for that certain category. So in administration I'd have this form where I'd be able to add the category name, some other relevant information to the category itself, and then these fields that would collect information on what HTML fields to present to the user when making an entry to this certain category.
For example this would be a Dog category:
Category name: Dog
Category enabled: 1
Category parent: Pets
Fields:
Title - text field (will be auto added to each category)
Breed - select field
Age - number field
Color - text field
Price - number field (will be auto added to each category)
Description - text area field (will be auto added to each category)
So now at this stage when the user created all these certain fields for the Dog category, Im having trouble figuring what would happen when the user hits the submit button to save this category. I thought of these two solutions:
Create a new model/table for each new category (Read linked question above) with all the HTML fields as columns and also store a row on the categories table with some basic info about this category
Store everything in the categories table and have a fields_json column which will store all HTML field information (I wont be actually storing HTML, but basic info what the fields are about then create the HTML form fields dynamically in a controller) as a JSON string. I would be able to present the fields nicely on create, but on update it would be a hassle to populate those fields (maybe) and a search function would not be very efficient with this alternative.
So what I'm looking for is a third alternative so I can fix my problem. What would be an efficient way to solve this problem and be able to have categories with different input fields and also be able to efficiently perform searches on these categories?
The project I'm working on is being created in Ruby on Rails 4 and the database is in MySQL.

For given scenario I would:
create table categories to store each category
create table category_fields to store each category field
create table collected_categories to store all collected data from category fields in serialized hash
Collected data can be easily (de)serialized into text column (no matter of db engine you will use).
Check those sources which utilize your problem: dynamic forms

Related

Linked tables vs json objects

So the question what is better to use a linked tables vs json objects in a mysql database for many to many relationship so for example you have a user table like this
id
name
email
and event table:
id
name
description
The question is if its better to add a extra text field toward the user table with text column where you store a json object where you put event ids in like this
user table:
id
name
email
json
with the json object looking something like this
{
{event_id: 1},
{event_id: 2},
etc
}
or have a linked table with
id
event_id
user_id
assuming you have a many to many relationship where one user can register for multiple events and one event can have multiple users. where you also want to count how much users belong to 1 event and also wanna ask which one is optimal to use for querying and performances while doing this in laravel.
Your linked table has all the information
SELECT COUNT(*) FROM linked_table GROUP BY event_id WHERE event_id = 10
So you now have the number of users that belong to one event.
even with mysql 8 you have to put much more work and code to get information.
Edit:
besides json are slightly better that comma separated field Is storing a delimited list in a database column really that bad?

How to eliminate database table row duplication

I have a question on databases and how information is displayed in regards to Primary and Foreign keys.
For example, there are three tables; Employees, Employee_tickets and Employee_comments.
Each employeecan have multiple tickets and also multiple comments. A foreign key is placed in the Employee tickets and Employee Comments table. My application is built in vb.net with Visual Studio and it is a desktop application. How can I query say.. Employee Name ('Jon Doe') and display all of his tickets in a grid as well as all of the comments people have made on him over time? I have created a View on the sql database which returns all of the information I require but for each ticket listed under ('Jon Doe') the View displays and Employee Name for every single ticket. Is there a way to display the employee name only once and then every ticket listed under that particular individual without displaying the Employee Name again or do I have to make Separate windows to segregate all of this?
This seems like a really dumb question and I cannot for the life of me figure out how to correctly display what is required in this situation.
Here is an example of what I am trying to explain:
So for troy there is one employee name entered in the Employee Names table, There is one CWB ticket entered in the CWB table but there are TWO PQ Cards entered in the PQR Ticket table. How Can I Display only one row for Troy and one Row for his CWB because there are only one of each entered in the tables then the two rows for the PQR Cards under his name?
I have created a view which gathers this information all into the one single view itself then bound the datagridview's to this View.
Your problem has nothing to do with databases. Rather, the issue is that you have an entity (the employee) that has two separate collections associated with it (tickets and comments) and you want to show the contents of both collections.
Doing this in a datagrid is difficult because in its simplest incarnation it's intended to show one collection of like items.
I can think of a number of possibilities:
In your code, convert each collection to a single string value and display that single string value on the row with the employee's name. This conversion could be to comma-separate a stringified version of each item in the collection (as suggested by BS123 in the comments) or could simply be a summary (eg "5 Tickets").
Put the basic employee information in one data grid and then have two additional data grids below it, one bound to the Tickets collection and one to the Comments collection.
Embed data grids directly in the main data grid, one in the Tickets column and one in the Comments column, and bind each one to the appropriate collection in the employee.
Your database structure is correct so don't change that, you simply need to solve the issue of presentation.
What you're missing here is a controller between your view and your model. Your view is presenting exactly what it was given to present - it's up to you to format it.
There are several possible solutions to this, and the correct one partially depends on needs and infrastructure.
If you infrastructure is solid and your needs are near real time, consider dropping separately querying to fill your second and third tables based on what is picked in the first. This will increase the load on the database, but your data will almost always be correct, and the data will come from the database the way you want to see it.
If the database-centered solution is not good for you, LINQ provides some good ways to filter your data into typed collections that would present exactly what you want the user to see.
To get the users:
Dim users = From l In data.lines
Group By FirstName = l.firstName, LastName = l.lastName
Into Tickets = Group, Count()
You can then present this object to your grid. While dynamic typing works here, I think it would be easier to manage view interactions with defined classes. I'll leave that part up to you. Do some searching on LINQ to fill in the rest of the blanks. It's pretty neat stuff.

Adding new columns to table dynamically for custom fields

I am building a custom field feature for my application. This allows the administrator to add custom profile fields for users to fill in depending on the site's needs.
The schema is simple
field_meta (store some metadata about the field)
================================================
id
type //type of field
field_name //name of the field in the fields table
render_data //Some data to use when rendering the form field
field
===================
id
name //Default field that can't be deleted
address //Default field that can't be deleted
customfield_1
customfield_2
The field_meta table is used to store some meta data for the field, so that we can render the form fields.
Each field is then stored in a new column in the field table.
Problem:
For usability and to not have to deal with users choosing reserved words or using non-english words for the column name, I will not be asking users to choose a name for the column name.
I am currently considering calling the column name by field type (there are quite a few types in the application (email, website, text, paragraphtext, etc), just to name a few) and adding a number. Some examples:
Email_1
Text_1
Text_2
Text_3
Email_2
etc
However, the problem with this approach is that it takes a fair bit of work to come up with the column name. I need to get all the columns, pick out the ones with the same column type as I am creating, parse for the largest number, and then create the column.
Is there a better strategy to do this? Or perhaps a totally different way to name the columns that eliminates these problems?
Don't try to dynamically add columns, that's a slow (and not good form) method.
Instead, store the extra columns in a new table, each with their own ID. Then have another table that stores a user ID, the extra column ID, and the attribute information for that user. This would imitate adding new columns without actually having to do so.
Edit:
Indeed it does sound like EAV. Schema:
Attributes{id:int, name:string}
Users{id:int, name:string, (any others needed…)}
Users_attributes{Attribute_id:int, User_id:int, Attribute_info:string}
Then just input any new attributes into Attributes (with incrementing ID), and any new user information into User_attributes with the appropriate User_id and Attribute_id.
I decided to go with my original approach, that is to basically create a column name consisting of the type and an incremented number:
Email_1
Text_1
Text_2
Text_3
While it takes a fair bit of effort to generate the name, this is only done when creating the profile fields, so the performance hit would only occur during that time.

User Defined Fields PHP Mysql

I am currently building a small crm application. I need each user to be able to define their own custom fields. I am currently building this crm using php and mysql.
Example: I have a "customer" table which has the standard fields: name, phone, address, email, etc. But i want to allow the user (unique session) to add fields that are custom to his/her business which are only accessible to him (not other users). I then want these custom fields to function just like all the other fields in the table (ability to search, send and received data). I am hoping i can accomplish this in mysql and php but am open to any technology or solution that is considered best practice. Thank you for your help.
This can be done by creating a table called "customfields" with the elements "id, fieldname, company_id", then another table that would associate those custom fields with data, eg "customercustomdata: id, customfields_id, customer_id". Associate "ownership" of a field the same way
To create a new custom field, "insert into customfields (fieldname,company_id) values ('Birthday',companyid);"
Does that help?
#Matt H: Is this method considered AEV or just standard relational db?
So because i will have many users in many dif industries that will want to add their own custom fields to a number of different tables (contacts, transactions, events, etc) i am assuming that i would need the customfield table to have a user_fk/id or company fk/id, a related table fk/id, an id, and a field name? Am i on the right track? Then in the need to create a 2nd table to hold the data for each custom field buy having a customfield fk/id, customer fk/id, id and a data field to hold the actual data. Is this correct?
Ok so once i build those two additional tables how do I add them to the contacts table so it looks like one big table for the user, instead of the 3 tables?
Thanks again for you help.
Answer
after much research i have found that most people who wish to accomplish this are using document databases not relational databases.
You could place an extra column for storing string data and store an array describing the contents for custom cells. For example:
$custom = array(
array("field" => "bikesOwned", "value" => 4),
array("field" => "travelled", "value" => 14)
);
then use something like PHPs json_encode to store that data in the extra cell. Then all you would need to do is decode and process the array.
Some people suggesting using the Entity-Attribute-Value design, but before you do, please read Bad CaRMa, a story about an EAV-like design that nearly destroyed a company because it was unmaintainable.
To solve this better, read How FriendFeed uses MySQL to store schema-less data. You can lump all the custom columns into a single BLOB, and store it that way. Then if you want individual attributes to be searchable, create a table for that attribute, that maps values back to the customers table.

Symfony 2 - create a form with a parent entity filtering the options of the child entity

I am new to symfony and PHP.
I have a problem that I hope someone can help:
supose we have 3 entities.
Groups, specialities, works; works belong to a speciality, speciality belong to a group.
Supose that I want to have a form to create a "work". I want to filter my specialities according to a select with the list of groups ( much like on a travel site where we get the destinations filtered by the origin).
So my form will only have 2 fields. The speciality and a name for the work. But in my view i must have 3 fields, 1 for groups that will filter the specialities and the fields belonging to the form.
Much like a booking flights site I must see the fields from the begining.
This as to be so simple, but I'm really stuck on it.
Thank you
At this moment I can come up with 2 solutions:
1) Use ajax.
On the request populate a selectbox with the groups. when you select one of the groups, all the specialities come into a different selectbox of that group.
2)
Use uri segments. Let the user first choose group, then go to a next page and let them choose a speciality. After that the user gets a form where he fills in the data.