3

Я надеюсь, что кто-то может помочь мне в лучшем способе сделать это. Я настраиваю на форму регистрации для людей, чтобы перечислить свои навыки/полномочия в различных работахСоздание динамической формы и модели на основе ввода пользователя

схемы вдоль этих линий с использованием Mongoid и наследования

class Person 
    include Mongoid::Document 
    field :name, :type => String 
    field :education, :type => String 
end 

class Accountant < Person 
    field :cpa, :type => Boolean 
    field :active_cpa, :type => Boolean 
end 

class SoftwareDeveloper < Person 
    field :full_stack, :type => Boolean 
    field :language, :type => Array 
end 

Таким образом, пользователи будут приходить на страницу регистрации MySITE .com/people/new, где будет форма для выбора различных заданий (перечисленных и сгруппированных по различным отраслям: финансы, инженерия, маркетинг) и на основе выбора пользователя, более подробное представление будет отображаться специально для этой функции работы , (например, разработчики программного обеспечения могут перечислить языки программирования, а бухгалтеры могут указать, есть ли у них CPA).

Мой вопрос: какой лучший способ справиться с этим на уровне контроллера и просмотра? Есть около 100 различных функций работы, которые я охватываю, поэтому я хотел бы комбинировать контроллер и просмотр вместо перенаправления пользователей на mysite.com/accountants/new или mysite.com/engineers/new и иметь контроллер/представление для каждого конкретной работы.

Может кто-нибудь, пожалуйста, поможет мне лучше всего подойти к этому? Я знаю, что мне придется использовать jQuery и, возможно, некоторые вызовы ajax для отображения подробных форм, но что мне делать с контроллером, потому что form_for сначала привязан к пользователям, а модель имеет ограниченные атрибуты, поэтому я не уверен, как получить параметры и передать их в params хэш с проверками для более конкретных заданий

ответ

2

У меня была проблема, как это недавно. Я закончил создание своей формы, используя form_for для базового типа Person в вашем случае. В форме я создал Fieldset для базовых полей и отдельных тегов Fieldset представлять дополнительные поля, доступные в каждом подклассе так:

<%= form_for @person do |f| %> 

<fieldset id="base"> 
    <%= f.label :name %> 
    <%= f.check_box :name %> 
    <!-- ... --> 
</fieldset> 

<fieldset id="accountant"> 
    <%= fields_for :accountant do |f| %> 
    <%= f.label :cpa %> 
    <%= f.check_box :cpa %> 
    <!-- ... --> 
    <% end %> 
</fieldset> 

<fieldset id="software_developer"> 
    <%= fields_for :software_developer do |f| %> 
    <%= f.label :full_stack %> 
    <%= f.check_box :full_stack %> 
    <!-- ... --> 
    <% end %> 
</fieldset> 

Это использование fields_for приведет в виде POST обеспечения вашей «создать» метод в контроллере с Params, как:

params[:person] = { :name => "Joe Smith", ... } 
params[:accountant] = { :cpa => true, ... } 
params[:software_developer] = { :full_stack => false, ... } 

в вашей форме, вы также хотите иметь какой-то способ определения типа задания. В моем случае, я использовал простой выберите тег:

<%= select_tag :job_type, options_for_select(@job_types) %> 

Это обеспечит вам Params [:] job_type в контроллере. Оттуда метод «create» должен определить, какой тип задания выбран пользователем, а затем создать правильный подкласс и использовать предоставленные параметры. Я использовал заявление о делах для этого:

case params[:job_type] 
when :accountant 
    @person = Accountant.new(params[:person].merge(params[:accountant])) 
when :software_developer 
    @person = SoftwareDeveloper.new(params[:person].merge(params[:software_developer])) 
when ... 
end 

Если у вас много подклассов, это может быть не очень масштабируемо. Итак, что вы можете сделать, это организовать, что params [: job_type] дает имя класса для создания в качестве значения, которое представляет форма. Тогда вы могли бы сделать что-то вроде:

@person = params[:job_type].constantize.new(params[:person].merge(params[params[:job_type].underscore]) 

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

Наконец, вы захотите использовать немного jQuery, чтобы скрыть и показать различные наборы полей, когда пользователь выбирает другой тип задания. Для этого прикрепите обработчик .change() к элементу select_tag и скройте все поля, а затем укажите один набор полей с «id», который соответствует выбранному типу задания. Дайте мне знать, если вам нужен пример кода для этого.

Как последний штрих, вы можете подумать о том, чтобы ваши задания задавались в частичном порядке, чтобы ваша основная форма имела только серию вызовов для отображения всех разных типов заданий.

Я не знаю, есть ли лучшие способы сделать это, но этот подход отлично подойдет для меня и позволил мне иметь один контроллер и множество представлений для управления созданием и редактированием целого родителя/ребенка дерево подкласса.

+0

Спасибо за это. Это было очень полезно. Я провожу в эти выходные, пытаясь реализовать это в своем коде. Не могли бы вы привести мне пример метода .change(), который вы упомянули? Я не уверен, должен ли я иметь форму, загружающую все различные поля для каждого типа job_type, или просто иметь базу и добавлять определенные поля на основе выбранного типа job_type. В любом случае, спасибо за вашу помощь до сих пор! –

+0

Да, я могу обновить ответ с помощью метода изменения примера. Одна вещь, которую вы можете сделать в методе .change, - это динамическая загрузка набора полей для выбранного типа задания с сервера. Некоторые люди выступают за AJAX, используя JSON, и это нормально. Но в таких случаях вы хотите, чтобы ваши отрывки формы были готовы к форматированию, загружаемым с сервера. Таким образом, у вас есть все ваши макеты, сделанные на стороне сервера в ERB или что-то еще, и вам не нужно возиться в javascript, создавая поля формы из JSON и т. Д. – OzBandit

+0

Возможно, вы захотите проверить, является ли 'params [: job_type]' авторизованное значение перед передачей его в '.constantize.new', чтобы избежать выполнения произвольного кода. – ybart

Смежные вопросы