1

I have an application that allows the user to drill down through data from a single large table with many columns. It works like this:

  • There is a list of distinct top-level table values on the screen.

  • User clicks on it, then the list changes to the distinct next-level values for whatever was clicked on.

  • User clicks on one of those values, taken to 3rd level values, etc.

There are about 50 attributes they could go through, but it usually ends up only being 3 or 4. But since those 3 or 4 vary among the 50 possible attributes, I have to persist the selections to the browser. Right now I do it in a hideous and bulky hidden form. It works, but it is delicate and suboptimal. In order for it to work, the value of whatever level attribute is on the screen is populated in the appropriate place on the hidden form on the click event, and then a jQuery Ajax POST submits the form. Ugly.

I have also looked at Backbone.js, but I don't want to roll another toolkit into this project while there may be some other simple convention that I'm missing. Is there a standard Rails Way of doing something like this, or just some better way period?

RubyRedGrapefruit
  • 12,066
  • 16
  • 92
  • 193
  • 1
    Funny, I have the same problem in an app I'm working on. I don't think there is a great answer to this, but hopefully someone else will enlighten us both. – Dave S. Jan 02 '13 at 03:13

2 Answers2

2

Possible Approaches to Single-Table Drill-Down

If you want to perform column selections from a single table with a large set of columns, there are a few basic approaches you might consider.

  1. Use a client-side JavaScript library to display/hide columns on demand. For example, you might use DataTables to dynamically adjust which columns are displayed based on what's relevant to the last value (or set of values) selected.
  2. You can use a form in your views to pass relevant columns names into the session or the params hash, and inspect those values for what columns to render in the view when drilling down to the next level.
  3. Your next server-side request could include a list of columns of interest, and your controller could use those column names to build a custom query using SELECT or #pluck. Such queries often involve tainted objects, so sanitize that input thoroughly and handle with care!
  4. If your database supports views, users could select pre-defined or dynamic views from the next controller action, which may or may not be more performant. It's at least an idea worth pursuing, but you'd have to benchmark this carefully, and make sure you don't end up with SQL injections or an unmanageable number of pre-defined views to maintain.

Some Caveats

There are generally trade-offs between memory and latency when deciding whether to handle this sort of feature client-side or server-side. It's also generally worth revisiting the business logic behind having a huge denormalized table, and investigating whether the problem domain can't be broken down into a more manageable set of RESTful resources.

Another thing to consider is that Rails won't stop you from doing things that violate the basic resource-oriented MVC pattern. From your question, there is an implied assumption that you don't have a canonical representation for each data resource; approaching Rails this way often increases complexity. If that complexity is truly necessary to meet your application's requirements then that's fine, but I'd certainly recommend carefully assessing your fundamental design goals to see if the functional trade-offs and long-term maintenance burdens are worth it.

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
  • This is a really unique situation in that the data in this large table actually *is* denormalized. It involves vehicle configurations and as such displays a wide range of variability across the different configurations. Your Item #2 is the approach I have taken, it's that I've done it in a little too complex of a fashion. My form mirrors the table exactly. It will be immensely nicer-looking if I simply serialize the request as JSON into a single field and modify it appropriately. Thanks! – RubyRedGrapefruit Jan 13 '13 at 17:28
1

I've found questions similar to yours on Stack Overflow; there doesn't appear to be an API or style anyone mentions for persisting across requests. The best you can do seems to be storage in classes or some iteration on what you're already doing:

1) Persistence in memory between sessions/requests

2) Coping with request persistence design-wise

3) Using class caching

Community
  • 1
  • 1
JoshDM
  • 4,939
  • 7
  • 43
  • 72