Как высушить бизнес-логику между Ruby на стороне сервера и Javascript на стороне клиента? - PullRequest
3 голосов
/ 19 апреля 2010

У меня есть модель Widget с наследованием (я использую наследование для одной таблицы, но она одинаково действительна для класса на таблицу). Некоторые из подклассов требуют определенного поля; другие нет.

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

Я создаю форму "Новый виджет" (app/views/widgets/new.html.erb) и хотел бы динамически показать / скрыть поле color на основе <select> для 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 %>

Я легко могу написать некоторый jQuery для наблюдения за onChange событиями на widget_type, но это будет означать добавление некоторой постоянной WidgetTypesThatRequireColor в мой Javascript. Достаточно просто сделать это вручную, но, скорее всего, оно отключится от классов модели Widget.

Я бы предпочел не выводить Javascript непосредственно в моем представлении, хотя я рассмотрел использование content_for(:js) и в моем шаблоне нижнего колонтитула есть yield :js. Есть идеи получше?

1 Ответ

3 голосов
/ 20 апреля 2010

Вот HTML, который я бы сгенерировал. Вы можете создать его из представления или помощника различными способами.

<select ...>
    <option class="widget colored">FooWidget</option>
    <option class="widget uncolored">BarWidget</option>
    <option class="widget colored">BazWidget</option>
</select>

Затем пусть jQ наблюдает за выбором и показывает или скрывает div в зависимости от класса выбранной опции.

...