Rails Devise Polymorphic - Get Render Partial Using Ajax
you are mixing up several things here.
- your routes define a default
if you need to select from a dropdown, there is no need to define a default value here. it just complicates things
match '/add_user' => 'registrations#new', :user => { :usertype => nil } match '/select/admin' => 'registrations#selectuser', :user => { :usertype => 'admin' } match '/select/player' => 'registrations#selectuser', :user => { :usertype => 'player' }
- you are not using the right form helpers
you need to use f.select
if you want to get an output of params[:user][:usertype]
. if your model does not have such a property, you can add it as an attr_accessor
to your model.
<%= label :usertype, "Select User Type" %><br /><%= select_tag(:usertype, options_for_select([['-- User Type --', nil], ['Admin', 'admin'], ['Player', 'player']], selected: '-- User Type --' )) %>
I think you've got a lot of problems, but the biggest is here:
nesteds = fields_for child_class_name.constantize.new do |rf|render :partial => child_class_name.underscore + '_fields', :locals => {:f => rf}
You're trying to render a "fields_for
" helper in a variable. The problem is this variable is treated as a string, which means that it's no longer a helper, and won't cause the fields_for
element to appear. This is further to the fact that we don't know what part of your system is not working --
Is your Ajax firing? Are your routes sending the request correctly?
Personally, I would re-think how this part of your system works
I would remove the logic from your rendered selectuser.js.erb, and put it into the controller, like this:
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
Then in your JS, you'd be able to let JS do what it was born to:
$("#selectuser").html("<%=j render :partial => @render, locals: {:f = @rf} %>");
This means that in your child_class_name_fields.html.erb, you need to have something like this:
<%= f.fields_for child_class_name.constantize.new do |rf| %> <%= rf.text_field :name %><% end %>
Update
I am actually struggling with this now, because I would do it totally differently. I would move the entire logic into the controller, and only send variables to the partial through the :render function.
I don't like the idea you're trying to generate "f.fields_for" on the fly -- it should be set already, and you only change the fields inside that block. It's a principle known as DRY (don't repeat yourself) programming. If you want, I can write my preferred version for you, instead of trying to monkeypatch this one?
In your controller file return
render json: {"fields" => render_to_string(partial: "admin_fields") }
when the controller returns json to your ajax function inject with the following -
$('#selectuser').html(fields)