Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Creating dynamic, CMS-like fields in rails for different post types

I am building a Rails 4 app that has many different types of posts (50+) and each type of post will have different fields. All posts will share fields and entities in common like :title, :body, :image, :category. Category will be the differentiator between each post type. Only admins can create categories. Say I create a category "sports". On top of the attributes above, it has attributes like :intensity, :equipment, :calories_burned. I have a users model and an admin model. Is there a way to create post types with custom fields/attributes to each type dynamically as an admin user?

3 Answers

There are a few different approaches to adding custom fields. You can use ActiveRecord Serialization to store the custom field definitions. You could also create another relationship from Category to define your custom fields, something like this:

ERD for Custom Fields

Once you've stored your custom fields you will need to add the additional logic to your view to add the correct fields to your form and then you'll need to store that information within the Post model or create an additional model that stores the values for the custom fields.

Overall it is fairly straightforward problem, you ultimately need to decide if it's better to store all that information within the Category and Post models or split it out into related models.

Kyle Daugherty
Kyle Daugherty
16,441 Points

Hey Daniel Reedy,

What tool did you use to design that schema. Looks sharp.

Thanks!

Daniel Reedy, are you missing a has_many :custom_fields association on the category model? This look much more straight forward when you illustrate it this way. How would you approach populating the views? Say some :custom_fields may require text_fields, selections, booleans..?

Artem Prytkov
Artem Prytkov
11,932 Points

@Daniel I think you missed a column in posts where you store actual values for custom attributes

@Jared Custom fields table has type column. If it store actual class, you have to write helper, which build custom field depending on that class,

My answer was not intended to be exhaustive and good catch on the diagram, I did forget to add the addition relationship for Category.

I've done something very similar in the past, to build a dynamic form builder, and I may see if I can abstract the code out of the project.

The short answer is I stored the values for the custom fields in another model, indexed by post so that validations could be included.

I wrote a blog post awhile back (which I originally forgot about while answering your question) that demos how I am doing dynamic validations in a project. In the article I discuss how we are dynamically rendering out forms which are defined using a database. Take a look and see if that helps with the implementation. Dynamic Validation in a Rails Model

Kyle Daugherty, I'm using Omnigraffle for the ERD diagram

Artem Prytkov
Artem Prytkov
11,932 Points

If you use PostrgeSQL as database, you might want to store informations about fields for each category (and responces for each post) in Hash. See this thread: stackoverflow.com/questions/8816176/how-can-i-store-a-hash-in-my-database

But it`ll require additional code for building forms, and saving/loading data from it.

Artem, thanks I thought about that last night and it makes total in terms of using a helper method to render form elements. Daniel, thanks a lot man, I'll check out your blog.