7

我已经从这个答案中实现了具有多个模型的设计注册。这个 tutsuser_type从路径中获取参数。我想用 select 改变它user_type。因此,当我在select_tag.

我有一些代码看起来像:

路线.rb

   namespace :cp do
    devise_scope :user do
     match '/add_user' => 'registrations#new'
     match '/select/admin' => 'registrations#selectuser', :user => { :usertype => 'admin' }
     match '/select/player' => 'registrations#selectuser', :user => { :usertype => 'player' }
    end
   end

注册控制器.rb

  def selectuser

    respond_to do |format|
      format.js
    end
  end

新的.html.erb

<h2>Add User</h2>

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <div><%= f.label :username, "Username" %><br />
  <%= f.text_field :username %></div>

  <div><%= f.label :email, "Email" %><br />
  <%= f.email_field :email %></div>

  <div><%= f.label :password, "Password" %><br />

  <%= f.password_field :password %></div>

  <div><%= f.label :password_confirmation, "Password Confirmation" %><br />
  <%= f.password_field :password_confirmation %></div>

  <div><%= f.label :usertype, "Select User Type" %><br />
  <%= f.select(:usertype, options_for_select([['-- User Type --', nil], ['Admin', 'admin'], ['Player', 'player']], selected: '-- User Type --' )) %>
   </div> 

   <div id="selectuser">
   </div>
  <% end %>

  <div><%= f.submit "Submit" %></div>
<% end %>

<script type="text/javascript">
$("#user_usertype").on('change', function() {
   var s = $(this).val();
       $.ajax({
              type: 'GET',
              url: 'http://localhost:3000/cp/select/' + s,
              dataType: "HTML"
              });
});
</script>

选择用户.js.erb

<%  params[:user][:usertype] ||= 'admin'

    if ["admin", "player"].include? params[:user][:usertype].downcase
      child_class_name = params[:user][:usertype].downcase.camelize
      usertype = params[:user][:usertype].downcase
    else
      child_class_name = "Admin"
      usertype = "admin"
    end


   nesteds = fields_for child_class_name.constantize.new do |rf|
     render :partial => child_class_name.underscore + '_fields', :locals => {:f => rf}
   end
%>
$("#selectuser").append("<%= j nesteds %>");

当我选择管理员值时,记录:

Started GET "/cp/select/admin" for 127.0.0.1 at 2013-10-21 17:00:04 +0700
Processing by Cp::RegistrationsController#selectuser as HTML
  Parameters: {"user"=>{"usertype"=>"admin"}}
  Rendered cp/registrations/_admin_fields.html.erb (4.0ms)
  Rendered cp/registrations/selectuser.js.erb (7.0ms)
Completed 200 OK in 22ms (Views: 22.0ms | ActiveRecord: 0.0ms)

_admin_fields.html.erb没有出现在#selectuser

4

4 回答 4

0

当您尝试渲染您的部分时,您必须添加一个 = :

<%=  params[:user][:usertype] ||= 'admin'
# ^ This makes whatever is being returned in this block to be added to the output
于 2013-10-29T23:57:13.990 回答
0

我认为你有很多问题,但最大的问题在这里:

nesteds = fields_for child_class_name.constantize.new do |rf|
render :partial => child_class_name.underscore + '_fields', :locals => {:f => rf}

您正在尝试fields_for在变量中呈现 " " 助手。问题是这个变量被视为一个字符串,这意味着它不再是一个助手,并且不会导致fields_for元素出现。这进一步说明了我们不知道您系统的哪个部分无法正常工作-

你的阿贾克斯火了吗?您的路线是否正确发送请求?


就个人而言,我会重新考虑系统的这一部分是如何工作的

我将从您呈现的selectuser.js.erb中删除逻辑,并将其放入控制器中,如下所示:

  def selectuser

  params[:user][:usertype] ||= 'admin'

    if ["admin", "player"].include? params[:user][:usertype].downcase
      child_class_name = params[:user][:usertype].downcase.camelize
      usertype = params[:user][:usertype].downcase
    else
      child_class_name = "Admin"
      usertype = "admin"
    end

    respond_to do |format|
      format.js { @render = child_class_name.underscore + '_fields', @rf = rf}
    end
  end

然后在你的 JS 中,你就可以让 JS 做它的诞生:

$("#selectuser").html("<%=j render :partial => @render, locals: {:f = @rf} %>");

这意味着在您的 child_class_name_fields.html.erb 中,您需要具有以下内容:

<%= f.fields_for child_class_name.constantize.new do |rf| %>
    <%= rf.text_field :name %>
<% end %>

更新

我现在实际上正在为此苦苦挣扎,因为我会以完全不同的方式去做。我会将整个逻辑移动到控制器中,并且仅通过 :render 函数将变量发送到部分。

我不喜欢你试图动态生成“f.fields_for”的想法——它应该已经设置好了,你只更改该块内的字段。这是一个被称为DRY(不要重复自己)编程的原则。如果你愿意,我可以为你写我喜欢的版本,而不是试图修补这个?

于 2013-10-23T09:41:47.277 回答
0

在您的控制器文件中返回

render json: {"fields" => render_to_string(partial: "admin_fields") }

当控制器返回 json 到您的 ajax 函数时,注入以下内容 -

$('#selectuser').html(fields)
于 2013-10-23T07:42:22.253 回答
0

你在这里混淆了几件事。

  • 您的路线定义了默认值

如果您需要从下拉列表中选择,则无需在此处定义默认值。它只会使事情复杂化

 match '/add_user' => 'registrations#new', :user => { :usertype => nil }
 match '/select/admin' => 'registrations#selectuser', :user => { :usertype => 'admin' }
 match '/select/player' => 'registrations#selectuser', :user => { :usertype => 'player' }
  • 您没有使用正确的表单助手

如果您想f.select获得params[:user][:usertype]. 如果您的模型没有这样的属性,您可以将其作为 an 添加attr_accessor到您的模型中。

<%= label :usertype, "Select User Type" %><br />
<%= select_tag(:usertype, options_for_select([['-- User Type --', nil], ['Admin', 'admin'], ['Player', 'player']], selected: '-- User Type --' )) %>
于 2013-10-21T13:07:21.240 回答