与设计用户相关联的多个模型-根据角色选择填写一个模型 [英] Multiple models associated with devise user - fill in one model based on selection of role

查看:57
本文介绍了与设计用户相关联的多个模型-根据角色选择填写一个模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用devise在以下字段中进行用户注册:电子邮件,密码和角色.

Im using devise for user registration with the fields: email, password, and role.

当用户从选择框(学生,教师,管理员)中选择一个角色时,我希望该应用呈现这些角色之一的嵌套字段.每个角色都存储不同的信息,并以自己的身份作为模型存在.

When the user selects a role from a select box (Student, Teacher, Admin), I want the app to render the nested fields for one of these roles. Each role stores different information and exists as a model in its own right.

我有一个JavaScript,可根据当前选择显示和隐藏适当的div.

I have a javascript which shows and hides the appropriate divs based upon the current selection.

问题是,除非我填写所有模型的字段,而不仅仅是我当前选择的模型的字段,否则表单无法提交.我意识到这是因为我正在渲染所有部分,然后仅使用javascript隐藏它们.

The problem is, the form fails to submit unless I complete the fields for ALL models, rather than just the currently selected model. I realise this is because I am rendering all the partials and then simply hiding them with the javascript.

问题::如何使用javascript动态地仅渲染包含当前所选模型的模型字段的部分?

Question: How do I use the javascript to dynamically render ONLY the partial containing the model fields for the currently selected model?

新注册视图

h2>Sign up</h2>

<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= f.error_notification %>

  <h3>Login Details</h3>

  <br />
  <div class = "row">
    <div class = "col-md-3"></div>
    <div class = "col-md-6"><div class = "panel panel-midnight">
      <div class = "panel-heading"><h3 class = "panel-title">Create an account</h3></div>
      <div class = "panel-body">
      <div class="form-inputs">

        <%= f.input :email, :required => true, :autofocus => true, :placeholder => "Enter email address" %>
        <br />
        <%= f.input :password, :required => true, :placeholder => "Password" %>
        <br />
        <%= f.input :password_confirmation, :required => true, :placeholder => "Confirm Password" %>
        <br />
        <%= f.input :role, :label => "I am a:", :collection => ["Student","Teacher","Admin"], :required => true %>
      </div>

      <h3>Profile</h3>


      <div id = "student_fields">
       <%= render partial: "student_fields", locals: {:f => f} %>
      </div>

      <div id = "teacher_fields">
        <%= render partial: "teacher_fields", locals: {:f => f} %>
      </div>

      <div id = "admin_fields">
        Admin
      </div>

      <br />

  <% end %>

  <br />

  </div>

  <div class = "col-md-3"></div>
  </div>
  </div>
  </div>


<! Javascript to show/hide specific fields for each role>


<script>


  $(document).ready(function(){
     if($('#user_role').val() != "Student"){
        $("#student_fields").css('display','none');
     }
     else{
        $("#student_fields").css('display','block');
     }

     $('#user_role').change(function(){
        if($(this).val() != "Student"){
          $("#student_fields").css('display','none');
        }
        else{
          $("#student_fields").css('display','block');
        }
     })
  });

  $(document).ready(function(){
       if($('#user_role').val() != "Teacher"){
          $("#teacher_fields").css('display','none');
       }
       else{
          $("#teacher_fields").css('display','block');
       }

       $('#user_role').change(function(){
          if($(this).val() != "Teacher"){
            $("#teacher_fields").css('display','none');
          }
          else{
            $("#teacher_fields").css('display','block');
          }
       })
    });

  $(document).ready(function(){
     if($('#user_role').val() != "Admin"){
        $("#admin_fields").css('display','none');
     }
     else{
        $("#admin_fields").css('display','block');
     }

     $('#user_role').change(function(){
        if($(this).val() != "Admin"){
          $("#admin_fields").css('display','none');
        }
        else{
          $("#admin_fields").css('display','block');
        }
     })
  });
</script>

推荐答案

JavaScript无法仅渲染"所需的字段.它既可以显示/隐藏(如您正在尝试的那样),也可以请求动态加载内容(又名AJAX).如果您想采用后一种方法,请考虑将您的个人资料部分更改为如下形式:

JavaScript cannot "render" only the fields that you want. It can either show/hide (as you're attempting to do) or request a dynamic load of content (aka, AJAX). If you'd like to go the latter route then consider changing your profile section to look like this:

<h3>Profile</h3>
<div id="profile"></div>

然后,您需要设置javascript以根据选择的角色向唯一的url发出请求,并在结果中填充#profile部分.这是一个基于jquery的想法...

Then you'll need to set up the javascript to make a request to a unique url based on which role is selected and fill the #profile section with the results. Here's a jquery-based idea...

$('#user_role').on('change', function(){
  switch( $('#user_role').val() ){
    case 'Teacher': targetUrl = '...'; break;
    case 'Admin': targetUrl = '...'; break;
    default:  targetUrl = '...'; break;
  }
  $('#profile').load( targetUrl );
});

警告:通常最好尝试在不使用ajax的情况下正常工作,然后在以后添加ajax,尤其是刚开始的时候.您可能需要考虑稍微修改后的注册,其行为更像是向导-用户可以首先提供用户详细信息(包括角色),而响应可能是要求用户在用户成功完成后提供其特定于角色的详细信息.已创建.

A word of warning: it's often best to try to get things working without ajax and then add the ajax later, especially if you're just starting out. You might want to consider a slightly modified registration that acts more like a wizard -- the user could first provide the user details (including role) and the response could be to ask the user to provide their role-specific details when the user is successfully created.

这篇关于与设计用户相关联的多个模型-根据角色选择填写一个模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆