Should Rails Developers be Database Developers

13 Jan 2015

One of the things that I noticed in most of the getting start with Rails books that they seemed determined in teaching you how to work with the database purely through ActiveRecord. ActiveRecord contains alot of analytical functions such as sum or count though these are very limiting compared to what you can in pure SQL especially with a database as powerful as Postgres which contains many of the features of Oracle from windows functions (analytical functions in Oracle) and materialised views.

Take a look at the following piece of SQL

SELECT cntyvol.COUNTY, cntyvol.YEAR, cntyvol.MONTH, cntyvol.VOLPC, cntyvol.created_at,soldvol.prcsold, prcchg.MONTH_PRICE_DIFF, row_number() OVER () id
FROM
(SELECT vcnty.county, vcnty.year, vcnty.month, ROUND((vcnty.volsum / tvol.volsum) * 100,2) VOLPC, created_at
FROM
(SELECT
COUNTY,
YEAR,
MONTH,
historic_analyses.created_at,
ROUND(SUM(resultvalue), 2) volsum
FROM historic_analyses, search_params sp, search_types st
WHERE search_types_id = st.id AND search_params_id = sp.id
AND st.searchtext = 'Volume Summary Property Types'
GROUP BY COUNTY, YEAR, MONTH, historic_analyses.created_at
) vcnty,
(SELECT
YEAR,
MONTH,
ROUND(SUM(resultvalue), 2) volsum
FROM historic_analyses, search_params sp, search_types st
WHERE search_types_id = st.id AND search_params_id = sp.id
AND st.searchtext = 'Volume Summary Property Types'
GROUP BY YEAR, MONTH
) tvol
WHERE tvol.year = vcnty.year
AND vcnty.month = tvol.month) cntyvol,
(SELECT volv.county, volv.year, volv.month, ROUND( (soldval /volsum * 100) ,2) prcsold
FROM
(
SELECT
COUNTY,
YEAR,
MONTH,
ROUND(SUM(resultvalue), 2) volsum
FROM historic_analyses, search_params sp, search_types st
WHERE search_types_id = st.id AND search_params_id = sp.id
AND st.searchtext = 'Volume Summary Property Types'
GROUP BY COUNTY, YEAR, MONTH
) volv LEFT JOIN
(
SELECT
COUNTY,
YEAR,
MONTH,
ROUND(SUM(resultvalue), 2) soldval
FROM historic_analyses, search_params sp, search_types st
WHERE search_types_id = st.id AND search_params_id = sp.id
AND st.searchtext = 'Sold Summary Prop Type'
GROUP BY COUNTY, YEAR, MONTH
ORDER BY COUNTY, YEAR, MONTH DESC
) soldv ON soldv.county = volv.county AND soldv.year = volv.year AND soldv.month = volv.month
) soldvol,
(
SELECT COUNTY, YEAR, MONTH,MONTH_PRICE_DIFF
FROM (
SELECT
COUNTY,
YEAR,
MONTH,
coalesce(round((AVERAGEVAL - LAG(AVERAGEVAL, 1)
OVER (PARTITION BY county
ORDER BY year, month)), 2), 0) MONTH_PRICE_DIFF,
valtime
FROM (
SELECT
COUNTY,
YEAR,
MONTH,
ROUND(AVG(resultvalue), 2) AVERAGEVAL,
MAX(year || trim(to_char(month, '09')))
OVER (PARTITION BY county) valtime
FROM historic_analyses, search_params sp
WHERE search_types_id = 5 AND search_params_id = sp.id
GROUP BY COUNTY, YEAR, MONTH
ORDER BY COUNTY, YEAR, MONTH DESC
) a
) perc
WHERE valtime = year|| trim(to_char(month,'09'))
) prcchg
WHERE soldvol.county = cntyvol.county AND soldvol.year = cntyvol.year
AND soldvol.month = cntyvol.month AND prcchg.county = cntyvol.county AND prcchg.month = cntyvol.month
AND prcchg.year = cntyvol.year)

Developing this in ActiveRecord would have been very time consuming and involved alot of lines of code considering ActiveRecord's sum function only operates on one group by at a time, ActiveRecord did prove it's worth when used as part of the web scraping code where database interaction is limited to inserts and updates as shown below

propertysite = PropertySite.create(:title => spage["itmtitle"], :propertytype => spage["type"], :beds => sbeds.to_i, :searchtext => @searchinput, :status => spage["status"], :lastdatescanned => DateTime.now )

Ruby on Rails applications are scaffolded and run as part of SQlite and all the tutorials focus on ActiveRecord which can lead developers down the wrong path by ignoring the powerful syntax they have available with SQL. Creating Database Independent code is not a good idea as the chances of your system moving from SQLlite to Postgres to MySQL over it's lifetime as slim,

It would be better if some of the books or Rails Blogs focused on Database Development as well as focusing 100 Percent on ActiveRecord.

Published on 13 Jan 2015 Find me on Twitter!