2011-10-30 15 views
11

Tengo la siguiente lista de selección.Rails select_tag with ajax action (Rails 3 y jQuery)

<%= select_tag "project_id", options_from_collection_for_select(@projects, "id", "title") %> 

Cuando el usuario selecciona una opción de la lista anterior, la siguiente lista se debe rellenar con los valores de base de datos en base a la selección anterior.

<%= select_tag "version_id", options_from_collection_for_select(??project.versions??, "id", "title") %> 

Creo que debería hacer uso del evento onchange, pero no tengo idea de cómo usarlo. Alguien me ayuda por favor. Gracias!

+1

ver este [esta cuestión] (http://stackoverflow.com/questions/5472045/multilevel-select-on-rails) – rubyprince

+0

@rubyprince He escrito sobre raíles 3 (!!). La función remote_function no existe en Rails 3 –

+0

oh..sorry, en ese caso puede reemplazar la función onchange con algo en jQuery ... Publicaré una respuesta con ella ... – rubyprince

Respuesta

25

Javascript

function update_versions_div(project_id) { 
    jQuery.ajax({ 
    url: "/update_versions", 
    type: "GET", 
    data: {"project_id" : project_id}, 
    dataType: "html" 
    success: function(data) { 
     jQuery("#versionsDiv").html(data); 
    } 
    }); 
} 

controlador

def edit 
    @projects = Project.all 
    @versions = Version.all 
end 

def update_versions 
    @versions = Version.where(project_id => params[:project_id]).all 
    render :partial => "versions", :object => @versions 
end 

Ver

<%= select_tag "project_id", options_from_collection_for_select(@projects, "id", "title"), :prompt => "Select a project", :onchange => "update_versions_div(this.value)" %> 
<div id="versionsDiv"> 
    <%= render :partial => 'versions', :object => @versions %> 
</div> 

parcial: _version.html.erb

<%= select_tag "version_id", options_from_collection_for_select(versions, "id", "title"), :prompt => "Select a version" %> 

también añaden una ruta para /update_versions en su routes.rb

match "/update_versions" => "<controller>#update_versions" 

En este caso, se debe reemplazar <controller> con el nombre del controlador.

No he probado el código, por lo que puede haber errores.

actualización

PullMonkey ha actualizado el código con Rails 3 ejemplo, que es obviamente superior de este código. Por favor, pago y envío http://pullmonkey.com/2012/08/11/dynamic-select-boxes-ruby-on-rails-3/ también

+0

Pocas mejoras a esto en términos de seguridad y manejo activo de registros: '@versions = Version.where ('project_id =?', params [: project_id]). first' La cláusula where tiene actualmente una falla de seguridad. Poner la cadena directamente podría dejar la consulta abierta a contenido malicioso. Además, actualmente está tomando ActiveRecord: Relation y no el objeto en sí. Por lo tanto, agregar un primer método solucionará esto. – JellyFishBoy

+0

Hi @ JellyFishBoy ... hay dos cosas aquí: - 'Version.where (project_id => params [: project_id])' - esta cláusula 'where' no deja una falla de seguridad, hasta donde yo sé. No estoy poniendo la cadena directamente, sino que paso un hash. Es la forma idiomática de escribir las condiciones en Rails. Rails se encarga de la seguridad, si lo proporcionamos como hash. Ver [Guía de rieles] (http://guides.rubyonrails.org/active_record_querying.html#hash-conditions) – rubyprince

+0

@ JellyFishBoy..Sobre el '.first', mi intención no es obtener el primer registro, sino obtener todo los registros, con la identificación del proyecto.Tiene razón al decir que devuelve una relación activerecord y activará la consulta de inmediato, pero esta relación activerecord disparará la consulta tan pronto como se invoquen métodos como 'inspeccionar',' cada'. Entonces, el código funcionará, pero acepto que es mejor llamar explícitamente. Añadiré eso. – rubyprince