How do I DRY up business logic between sever-side Ruby and client-side Javascript?

Posted by James A. Rosen on Stack Overflow See other posts from Stack Overflow or by James A. Rosen
Published on 2010-04-19T16:47:48Z Indexed on 2010/04/19 21:43 UTC
Read the original article Hit count: 239

Filed under:
|
|
|
|

I have a Widget model with inheritance (I'm using Single-Table Inheritance, but it's equally valid for Class-per-Table). Some of the subclasses require a particular field; others do not.

class Widget < ActiveRecord
  ALL_WIDGET_TYPES = [FooWidget, BarWidget, BazWidget]
end

class FooWidget < Widget
  validates_presence_of :color
end

class BarWidget < Widget
  # no color field
end

class BazWidget < Widget
  validates_presence_of :color
end

I'm building a "New Widget" form (app/views/widgets/new.html.erb) and would like to dynamically show/hide the color field based on a <select> for widget_type.

<% form_for @widget do |f| %>
  <%= f.select :type, Widget::ALL_WIDGET_TYPES %>
  <div class='hiddenUnlessWidgetTypeIsFooOrBaz'>
    <%= f.label :color %>
    <%= f.text_field :color %>
  </div>
<% end %>

I can easily write some jQuery to watch for onChange events on widget_type, but that would mean putting some sort of WidgetTypesThatRequireColor constant in my Javascript. Easy enough to do manually, but it is likely to get disconnected from the Widget model classes.

I would prefer not to output Javascript directly in my view, though I have considered using content_for(:js) and have a yield :js in my template footer. Any better ideas?

© Stack Overflow or respective owner

Related posts about ruby

Related posts about ruby-on-rails