Rails嵌套表单 - >不同的待遇取决于价值

时间:2015-06-04 06:58:23

标签: ruby-on-rails forms nested

关于嵌套表单我有这个棘手的问题。只是说我有以下型号:

  1. restaurant
  2. 员工,员工所属的餐厅。
  3. 我在员工模型中也有两种类型的员工,

    1. 经理
    2. 员工
    3. managers通过manager模型中的employees属性指定,boolean<%= f.simple_fields for :employees do |f| %> <%= render 'employee_fields', :f => f %> <% end %>

      当我编辑每个餐馆的员工名单时,它是通过嵌套的形式,即:

      <%= render 'manager_fields', :f => f %>. 
      

      我的问题:有没有办法根据员工的类型呈现不同的部分表格?例如,如果当前员工是经理,那么

      <%= render 'staff_fields', :f => f %>.
      

      否则,如果当前员工是员工,那么

      jQuery(document).ready(function() {
        jQuery('#submit').click(function() {
          var options = {
            'name': {
              required: true
            },
            'email': {
              required: true,
              email: true
            },
            'number': {
              required: true,
              digits: true
            },
            'select': {
              required: true
            },
            'select-multiple': {
              required: true
            },
            'radio': {
              required: true
            },
            'checkbox': {
              required: true
            },
            'checkbox-single': {
              required: true
            },
            'multiple-emails': {
              required: true,
              multipleEmails: true
            }
          };
      
          if (customValidation(options)) {
            alert('Form validated!');
          } else {
            alert('Form not validated!');
          }
        });
      });
      
      function customValidation(options, bindEvents) {
        /***
      		Function is based on jQuery Validation Plugin v1.13.1 but doesn't require a <form> tag
      	
      		Add custom validations in this function as required
      		
      		Currently supported validations are:
      		
      		Required - Field cannot be blank
      		Email - Validates an email address
      		Mutliple Emails - Validates mutliple email addresses
      		Number - Validates a decimal number
      		Digits - Validates digits only
      		
      		Todo:
      		
      		Equal To validation
      		Allow specifying parent element for Checkbox and Radio elements to apply an error class
      		Allow specifying custom error and success functions through function parameter and individual options			
      	***/
      
        var fieldsValid = true;
        bindEvents = (typeof bindEvents === 'undefined') ? true : bindEvents;
        var errorDiv = jQuery('#errorDiv');
      
        jQuery.each(options, function(elementIdorName, rules) {
          var element = (jQuery('#' + elementIdorName).length) ? jQuery('#' + elementIdorName) : jQuery('input[name=' + elementIdorName + ']:first');
          var elementType = element.prop('type');
          var elementName = element.prop('name');
      
          var elementValid = true;
      
          // First remove any validation errors
          jQuery('.error-' + elementName).hide();
      
          jQuery.each(rules, function(rule, ruleOption) {
            // Required
            if (rule == 'required' && ruleOption == true) {
              // Select
              if (elementType && (elementType.toLowerCase() === 'select' || elementType.toLowerCase() === 'select-one' || elementType.toLowerCase() === 'select-mulitple')) {
                var val = element.val();
                if (val && val.length > 0) {
                  // Do nothing
                } else {
                  elementValid = false;
                }
              }
      
              // Checkbox and Radio
              if ((/radio|checkbox/i).test(elementType)) {
                if (jQuery('input[name=' + elementName + ']:checked').length > 0) {
                  // Do nothing
                } else {
                  elementValid = false;
                }
              }
      
              // Text, Email, Number and Textarea
              if (jQuery.trim(element.val()).length > 0) {
                // Do nothing
              } else {
                elementValid = false;
              }
      
              if (!elementValid) {
                fieldsValid = false;
                if (jQuery('.error-' + elementName).length == 0) {
                  errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                } else {
                  jQuery('.error-' + elementName).show();
                }
              }
            }
      
            // Email
            if (rule == 'email' && ruleOption == true) {
              if ((/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/).test(element.val())) {
                // Do nothing
              } else {
                elementValid = false;
              }
      
              if (!elementValid) {
                fieldsValid = false;
                if (jQuery('.error-' + elementName).length == 0) {
                  errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                } else {
                  jQuery('.error-' + elementName).show();
                }
              }
            }
      
            // Number
            if (rule == 'number' && ruleOption == true) {
              if ((/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/).test(element.val())) {
                // Do nothing
              } else {
                elementValid = false;
              }
      
              if (!elementValid) {
                fieldsValid = false;
                if (jQuery('.error-' + elementName).length == 0) {
                  errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                } else {
                  jQuery('.error-' + elementName).show();
                }
              }
            }
      
            // Digits
            if (rule == 'digits' && ruleOption == true) {
              if ((/^\d+$/).test(element.val())) {
                // Do nothing
              } else {
                elementValid = false;
              }
      
              if (!elementValid) {
                fieldsValid = false;
                if (jQuery('.error-' + elementName).length == 0) {
                  errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                } else {
                  jQuery('.error-' + elementName).show();
                }
              }
            }
      
            // Multiple Emails
            if (rule == 'multipleEmails' && ruleOption == true) {
              var emailsArr = element.val().replace(/\s/g, '').split(/,|;/);
      
              for (var i = 0; i < emailsArr.length; i++) {
                if ((/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/).test(emailsArr[i])) {
                  // Do nothing
                } else {
                  elementValid = false;
                }
              }
      
              if (!elementValid) {
                fieldsValid = false;
                if (jQuery('.error-' + elementName).length == 0) {
                  errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                } else {
                  jQuery('.error-' + elementName).show();
                }
              }
            }
          });
      
          if (bindEvents) {
            var currentOption = {};
            currentOption[elementIdorName] = rules;
      
            // Bind events to validate on the fly
            switch (elementType) {
              case 'text':
              case 'email':
              case 'number':
              case 'textarea':
                element.unbind('keyup.customValidation-' + elementName).bind('keyup.customValidation-' + elementName, function(e) {
                  return customValidation(currentOption, false);
                });
                break;
              case 'radio':
              case 'checkbox':
                jQuery('input[name=' + elementIdorName + ']').each(function() {
                  jQuery(this).unbind('click.customValidation-' + elementName).bind('change.customValidation-' + elementName, function(e) {
                    console.log(e);
                    return customValidation(currentOption);
                  });
                });
                break;
              case 'select':
              case 'select-one':
              case 'select-multiple':
                element.unbind('change.customValidation-' + elementName).bind('change.customValidation-' + elementName, function(e) {
                  return customValidation(currentOption, false);
                });
                break;
            }
          }
        });
      
        return fieldsValid;
      }

4 个答案:

答案 0 :(得分:3)

是的,使用三元运算符:

<%= render f.object.manager? ? 'manager_fields' : 'staff_fields' , :f => f %>

如果您可以更改设计,我会为您提供更好的解决方案。其后如下:

使用Rails enum功能。

使用迁移在desgination模型中将字段Employee添加为整数字段。

然后在模型中:

enum designation: [ :staff, :manager ]

然后,您将在designation列中存储,manager(值为1)或staff(值为0)。现在在视图内部调用<%= render f.object.desgination , :f => f %>。你应该有_manager.html.erb_staff.html.erb 2个部分。

你完成了!

答案 1 :(得分:3)

是的,但这可能看起来有点难看:

<%= f.simple_fields for :employees do |f| %>
  <%= render (f.object.manager? ? 'manager_fields' : 'staff_fields'), :f => f %>
<% end %>

我可能会创建一个帮助方法,例如在ApplicationHelperEmployeesHelper文件中:

def get_employee_partial(employee)
  employee.manager? ? 'manager_fields' : 'staff_fields'
end

然后以形式:

<%= render get_employee_partial(f.object), :f => f %>

答案 2 :(得分:2)

您可以通过执行以下操作来实现条件渲染:

<%= f.simple_fields for :employees do |f| %>
  <% if f.object.manager? %>
    <%= render 'manager_fields', :f => f %>
  <% elsif f.object.staff? %>
    <%= render 'staff_fields', :f => f %>        
  <% end %>
<% end %>

如果您只计划在Employee模型中只有managerstaff个角色,那么您可以使用三元运算符来简化上述操作,例如 R_O_R '答案。

您可能希望从视图模板中抽象出条件逻辑。你可以通过创建一个帮助方法来实现这一点,如 Surya 的回答所示。

希望有所帮助!

答案 3 :(得分:1)

<%= f.simple_fields for :employees do |e| %>
  <% partial_name = e.object.manager? ? 'manager' : 'staff' %>
  <%= render "#{partial_name}_fields" %>
<% end %>