0

I have a request model. A request has one classification. What I want to set up is to store a bunch of form fields in the DB. Their types, names etc. Different classifications will have different form fields for the user to fill out on a request form. So ultimately User creates new request with classification C, and they are presented with a form with the appropriate fields for classification C.

I would like the values stored in a table with the request. My question is how should this be modeled?

Request has one classification. Classification has_many requests.

I'm just not sure what to do with the dynamic form fields. I would like to be able to create the fields and attach them to the classification. So if first name, last name are fields needed I wouldn't have to create them for every classification. Just create them once and set associate them with a classification through a join table.

Looking for advice on how to model this out and be able to easily reference them from a request.

Thanks! Any info or thoughts are appreciated.

2 Answers 2

1

I would say that you should first try to model it according the relational model as far as possible.

# beware of potential conflicts with this name as it clashes with core method  in controllers
class Request < ApplicationRecord
  has_many :classifications
end
class Classification < ApplicationRecord
  belongs_to :request
end

Model everything you know you can normalize. It's usually more then you think.

Dealing with data that doesn't adhere to a fixed schema can then be dealt with a few ways:

  1. Just define all the fields and live with a few nulls here and there.
  2. The Entity–attribute–value (EAV) pattern. This classic approach consists of a separate table where each row represents a value for a classification eg rails g model ClassificationAttribute classification:references attr_name attr_value. This is largely made obsolete by JSON data types.
  3. A JSON/JSONB column. This additional column would be used to shove any unstructured data that cannot be normalized.
  4. Serialized data columns. This also made obsolete by JSON/JSONB.

All of these can be combined with the Single Table Inheritance pattern.

If classification can be broken down into a limited number of variants you could consider Multiple Table Inheritance where you store the base data in the classification table and then use separate tables for the more specific data. Rails delegated_type feature can be used for this.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I was trying to avoid a JSON column but if that is the best way I can work with that. This is great info!
0

Your question is really confused and it is hard to understand what you are trying to achieve. But a few remarks:

  • You say "Request has one classification. Classification has_many requests" But if Request has one classification. Then classification should belongs to request. This way The Classification model holds a field called request_id (foreign key) that will help ActiveRecord link the two models together. (The child model is the one holding a foreign key) If each is the parent of the other (has_one or has_many), then where is the foreign key ?

  • dynamic fields is not something possible. Your databse if hard coded: each field is declared in the relational database and Rails ActiveRecord's allows to access it easily and validate it. There is indeed a solution: have one of the model holds a JSON or JSONB field. And the value instead of being of the common types: string, text, integer.. be of JSON type and holds a value that is converted to a hash by Rails :

    { first_name: "Arthur", last_name: "Smith", age: "23" }

This is pretty convenient for shopping carts as you can save an actual list of items rather than an association. Having an association would need to version your items changes (when the price of an item changes for example) which need some good engineering. The question is : is it what you really want to do ? Because this is an option that doesn't fit all apps or uses.

  • Also you say the request depends on the classification. I have mentionned the problem of the foreign key above. But it seems weird that one of your record behavior is set by a direct relationship relationship. Who creates the classification ? Is it one of the app models such as the User ? an Admin ? or is it seeded by the app creator (then Classification is a standalone model) ? In this case the classification preexists the request the Request and maybe a has_and_belongs_to_many association (a join table ) would fit better...

Maybe give us a clearer view of what you want to achieve with real life examples so we can help further

2 Comments

Using JSON to model a shopping cart is actually a horrible idea. The accepted solution to that problem is to just create a join table between orders and products that represents each row on a an order form and which records the price at the time of purchase - rails g model line_item order:belongs_to product:belongs_to price:decimal.
A valid use case for JSONB would instead be to model the additional specifications of a product if the table represents a bunch of very different real world items.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.