There are multiple things to consider here.
The first problem is to get your data out of the HTML form. If you use the standard Rails way of naming your form inputs, it's quite simple.
<input name="my_fields[value1]">
<input name="my_fields[value2]">
<input name="my_fields[sub1][value1]">
<input name="my_fields[sub1][value2]">
If you name them like that they can be accessed "en bloc" using the params hash via params[:my_fields], which gives you another hash containing your data.
Then you have to choose which way to save this data in your model. There are several options:
1. Use a string attribute
Just use a string or text column and assign a JSON string:
@my_model.my_data = params[:my_fields].to_json
- Pro: A very simple solution.
- Contra: SQL queries virtually impossible. Processing with Rails requires manually parsing of the data string.
2. Use a serialized hash
Use a string or text column and declare it as serializable on your model
serialize :my_data, Hash
Then you can use this column as it was a simple hash and Rails will perform the reading and writing operations.
@my_model.my_data = params[:my_fields]
- Pro: Still a simple solution. No messing with JSON strings. Processing with Rails much easier.
- Contra: SQL queries virtually impossible. A call to
to_json is necessary if you need a real JSON string.
3. Use specialized JSON database types
In case you need to be able to query the database using SQL the solutions above won't work. You have to use specialized types for that.
Many DBMS provide structured datatypes in form of XML or even JSON types. (PostgreSQL for example)
- Pro: Database queries are possible.
- Contra: Custom parsing and serialization necessary, migrations ditto. This solution might be over-engineered.
Update: Since Rails 5 JSON column types are supported. If you are using PostgreSQL or MySQL just use t.json (or t.jsonb) in your migration and use that attribute like a regular hash.