Splitting Rails DOM ids with RegEx Look Aheads

by Irish on October 15, 2010

In my Rails erb views I make good use of the dom_id view helper method. It basically introspects the object you pass to it and creates a unique id to use in your markup, based on the object type and database id. So for example if I had a Post with id 1, I could do:

    2 <li id="<%= dom_id(@post) %>">

And it would be rendered as

    2 <li id="post_1">

This is fine until you use dom_id on an object with a compound name like EmailNotification. Now dom_id will create a unique id like


Which is still good until I’m doing some front-end testing and I’m parsing these dom ids to find their related db records. Now I need to split “email_notification_1″ in a way that easily separates the object class from the identifier. How would you do that?

Well, what we can do here is use an advanced Regular Expression feature called a negative look ahead. We want to say, “split the string on the last underscore”.

A negative look ahead uses the ?! syntax in parenthesis, everything that follows ?! in the parenthesis will be used in the negative look ahead matching. So in our case we want to say, there should be a underscore that can be followed by any character except another underscore. The pattern would like like this:


We can confirm in irb

$ ree-1.8.7-head > x = "email_notification_1234"
=> "email_notification_1234"
ree-1.8.7-head > klass, id = x.split(/_(?!.*_)/)
=> ["email_notification", "1234"]

Likewise, If we wanted to split the dom_id on the first underscore we could just use a regular look ahead. It is similar but uses the ?= syntax.

$ ree-1.8.7-head > x.split(/_(?=.*_)/)
=> ["email", "notification_1234"]

{ 2 comments… read them below or add one }

Dom October 16, 2010 at 7:13 pm

Very handy – thanks!


Joshua Pinter July 28, 2022 at 11:51 am

Super handy! Here’s a little snippet to take it further and convert it to ActiveRecord objects:

dom_ids = params[ :dom_ids ].split( “,” ) # “facility_2035637462,diagram_184″ => [ "facility_2035637462", "diagram_184" ]

objects = dom_ids.collect do |dom_id|
klass, id = dom_id.split( /_(?!.*_)/ ) # Parse out the class and the id from the dom_id String.
klass.classify.constantize.find( id )


Leave a Comment

Previous post:

Next post: