March 3, 2012

Adopting a Table with Schema using Data Module

When working with medium to larger sized web applications, inevitably the requirement comes up for some advanced data reporting. The spectrum of requests here can obviously be pretty broad and is often beyond what you can accomplish with the default tables provided by Drupal and the installed modules. This tends to lead us to creating custom tables to track and manage the requested reports. Along with writing all of the necessary CRUD functions to make sure our new table is managing data appropriately, we also have to provide some sort of display or an export. Views can handle this latter requirement quite nicely. So it is here that we can turn to modules like Data or the now depricated Table Wizard to bring our new table under views "control." This gives us the added bonus of taking the display configuration out of the hands of the developer and placing it into the site builder/administrator's domain.

In a recent project just such a reporting request came up. The report was fairly complex and was to be visible to a larger subset of users. I wound up managing this report with a custom table and I turned to Data module to allow views to handle the output. After installing my custom module which created the custom table, I navigated to admin/build/data/adopt. Expecting to see my table in the list of "adoptable" tables, I was a bit confused when it was nowhere to be found. After a bit of digging I realized that tables declared using Schema API were considered "owned" by the module and not included in the list of adoptable tables. This makes some sense as you don't want just any table adopted by Data. Just imagine when an admin who's not quite sure what he or she is doing, decides to adopt and then drop the node table. I'd rather not...

So this leaves us with the question, "How do I get Data module to adopt my table?" From what I can tell, the creators of the data module expect us to use the Data API to handle table creation and CRUD. Personally I don't like the idea of this. I already understand and like working with Drupal's core Schema API, and don't want to adopt another layer of abstraction. I only want to utilize Data module to throw my table up to views. So after looking through how adoption is handled in the module, I found that really there is nothing preventing Data from adopting these schema declared tables. They are simply being made unavailable to the form at admin/build/data/adopt. This lead me to attempt to adopt my table right after it is generated in my module's .install file. This wound up working quite nicely and is implemented as follows:

function my_module_install() {
  //install schema as normal
  //make sure we have the data module
  include_once(drupal_get_path('module', 'data') .'/data.module');
  //instanciate the table we just created with the DataTable class
  $my_table_object = DataTable::instance('my_table');
  //tell Data module to adopt the table

After installing the module you should be able to see your custom table at admin/build/data. Data module is now obviously a dependency so be sure that it is installed and enabled before installing your custom module.

I realize that I could write my own views handlers for the custom table data I am providing, but I have found that to be a fairly time consuming (and often esoteric) task. When all we are after is a single, somewhat unique report, I feel that integration with the Data module and it's corresponding integration with views is simple, quick, and more than adequate.

Ryan Oles