2013-10-18 73 views
7

我已經實現了使用this answer的多個模型設計註冊。這從路徑獲得參數user_type。 我想用選擇user_type對此進行更改。因此,當我在select_tag上選擇一個值時,param user_type將會得到。Rails設計多態 - 使用Ajax獲取渲染部分

我有一些代碼看起來像:

的routes.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 

registrations_controller.rb

def selectuser 

    respond_to do |format| 
     format.js 
    end 
    end 

new.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> 

selectuser.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

+0

如果性別是所有關於男性和女性,沒有必要去碰服務器,只需在模板代碼吧。 –

+0

@BillyChan:我不知道你是什麼意思? – itx

回答

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]輸出。如果你的模型沒有這樣的屬性,你可以將它作爲attr_accessor添加到你的模型中。

<%= label :usertype, "Select User Type" %><br /> 
<%= select_tag(:usertype, options_for_select([['-- User Type --', nil], ['Admin', 'admin'], ['Player', 'player']], selected: '-- User Type --')) %> 
+0

謝謝phoet,我試過了,但沒有變化,仍然無法使用。 – itx

+0

我有屬性usertype用戶模型 – itx

0

在你的控制器文件返回

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

當控制器返回JSON到你的Ajax功能具有以下注入 -

$('#selectuser').html(fields) 
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元素。這進一步說明我們不知道你的系統的哪部分工作不正常 -

你的Ajax是否正在發射?您的路線是否正確發送請求?


就個人而言,我會重新考慮你的系統的這部分如何工作

我想從你的渲染selectuser.js.erb刪除邏輯,並把它送入控制器,這樣:

然後在你的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 (don't repeat yourself)編程的原則。如果你願意,我可以爲你寫我的首選版本,而不是試圖monkeypatch這一個?

+0

感謝豐啄,我看你的代碼將是錯誤,請參閱'nesteds = fields_for child_class_name.constantize.new do | rf |'wirhout'end'? – itx

+0

嗯,我沒有看到!我會以不同的方式執行代碼,說實話^ _^ –

+0

但是當你嘗試你的代碼時,出現'語法錯誤,意外的$結束,期待keyword_end'的錯誤。如果'nesteds'不會使用什麼變量'嵌套'。 – itx

0

你必須添加=當你試圖渲染你的部分:

<%= params[:user][:usertype] ||= 'admin' 
#^This makes whatever is being returned in this block to be added to the output