all jazz
all jazz

Reputation: 2017

Rails app design - how to make it modular

I have a complicated questions that I've been stressing my head with for the last few days. I'm wondering what would be the best code arcitecture approach in resolving the following issue:

I have a web app that creates widgets. Each widget can have its own template (theme) - there are multiple templates that user can choose between. User can customize specific parameters for each widget template such as color, text, size, etc..

Each template has its own fields (with default settings), html template file and stylesheet.

What would be the best approach in Rails app, so that it would be transparent, logical organization, easy to change and create new templates? I would like to keep it simple and modular.

We don't plan to change templates often, so its okay if they are hardcoded.

I was thinking of 2 options: 1. create a model Template, which defines fields with default settings (serialized text), view template and stylesheet 2. create a model, which would point to a Template specific class, that would derive from the parent Template file.. this would give much more flexibility

The template should return stylesheet and template view with inserted configured values.

I would really appreciate if someone could point me to some good practices that I could use, and not reinvent the wheel and make it too complicated or useless. Any feedback is highly appreciated.

Thanks a lot!

Upvotes: 1

Views: 475

Answers (1)

Vilmos Csizmadia
Vilmos Csizmadia

Reputation: 326

I believe an architecture like this one satisfies all of the requirements you specified above.

First, you have your two "core" models and their (very basic, haha) fields:

User

  • :id
  • :name

Widget

  • id
  • name

Next, you have the ThemeTemplate model, which belongs_to Widget and is responsible for storing the default attribute values along with your CSS and HTML code templates:

ThemeTemplate

  • id
  • widget_id
  • name
  • attributes, which stores a simple JSON hash of your attribute key/value pairs; for example: {width:50, height:100}
  • css_code_template
  • html_code_template

The css_code_template and html_code_template field should contain easily replaceable attribute key markers. For example, {{width}} and {{height}}.

Now, you need a way to bind the Widget to the User before we tackle our last model.

UserWidget

  • id
  • user_id
  • widget_id
  • theme_id, which stores the ID of the currently selected Theme (see below)
  • generated_css_code *
  • generated_html_code *

  • These two are optional in case you don't want to keep calling the generate_css_code and generate_html_code methods of Theme.

Last but not least, we have the model that stores all the custom attribute values.

Theme

  • id
  • name
  • user_widget_id
  • theme_template_id
  • custom_attributes, which stores a simple JSON hash of attribute key/value pairs; for example: {width:55, height:105}

This model should also have the generate_css_code and generate_html_code methods, which should read the code from the css_code_template and html_code_template of ThemeTemplate and replace the attribute key markers with their custom (from Theme) or default (from ThemeTemplate) values.

The problem with custom templates is you always want to make sure you have plenty of error detection in place.

Needless to say, the example I described above is a very simple way of tackling your requirements. One enhancement could be using a "NoSQL" database (such as MongoDB) for storing your attributes.

Upvotes: 2

Related Questions