ruby-on-rails ruby ruby-on-rails-3 autocomplete acts-as-taggable-on

ruby on rails - Cómo usar jquery-Tokeninput y Acts-as-taggable-on



ruby-on-rails ruby-on-rails-3 (6)

No sé si esto es la totalidad de su error, pero no está llegando a la URL correcta con el complemento tokenInput.

Esta

$("#product_tag_list").tokenInput("/products/tags.json"), {

debiera ser

$("#product_tag_list").tokenInput("/products.json"), {

Como dije, no sé si este es el único problema que tienes, pero si cambias esto, ¿funciona?

EDITAR:

Nunca he usado ActsAsTaggableOn . ¿Crea un modelo de Tag para que lo use?

Por lo que se ve en github , si desea consultar todas las etiquetas, es posible que tenga que usar su espacio de nombres en lugar de solo Tag , lo que significa ActsAsTaggableOn::Tag . Por ejemplo, puede ver cómo acceden a Tag s directamente en algunas de las especificaciones .

Así es como utilizas la función autocompletar con jQuery Tokeninput y ActsAsTaggableOn .

En mi situación, estoy usando una forma anidada, pero no debería importar. Todo a continuación es código que funciona.

Código

Modelo del Producto:

attr_accessible :tag_list # i am using the regular :tag_list acts_as_taggable_on :tags # Tagging products

Controlador de productos:

#1. Define the tags path #2. Searches ActsAsTaggable::Tag Model look for :name in the created table. #3. it finds the tags.json path and whats on my form. #4. it is detecting the attribute which is :name for your tags. def tags @tags = ActsAsTaggableOn::Tag.where("tags.name LIKE ?", "%#{params[:q]}%") respond_to do |format| format.json { render :json => @tags.map{|t| {:id => t.name, :name => t.name }}} end end

Rutas:

# It has to find the tags.json or in my case /products/tags.json get "products/tags" => "products#tags", :as => :tags

Application.js:

$(function() { $("#product_tags").tokenInput("/products/tags.json", { prePopulate: $("#product_tags").data("pre"), preventDuplicates: true, noResultsText: "No results, needs to be created.", animateDropdown: false }); });

Formar:

<%= p.text_field :tag_list, :id => "product_tags", "data-pre" => @product.tags.map(&:attributes).to_json %>

Problema 1 (SOLUCIONADO)

Debe tener la línea:

format.json { render :json => @tags.collect{|t| {:id => t.name, :name => t.name }}}

Nota: también puede usar @tags.map aquí y no tiene que cambiar el formulario tampoco.

A continuación se encuentran los 2 problemas sobre por qué necesita hacer esto:

Tengo la siguiente Tag : {"id":1,"name":"Food"} . Cuando guardo un Product , etiquetado como "Food" , debe guardar como ID: 1 cuando busca y encuentra el nombre "Food" . Actualmente, guarda una nueva Tag con una nueva identificación que hace referencia al ID de "Food" , es decir, {"id":19,"name":"1"} . En su lugar, debería encontrar la ID, mostrar el nombre y hacer un find_or_create_by para que no cree una nueva Tag .

Problema 2 (SOLUCIONADO)

Cuando voy a products/show para ver las etiquetas, hago <%= @product.tag_list %> . El nombre aparece como " Etiquetas: 1 ", cuando realmente debería ser " Etiquetas: Comida ".

¿Cómo puedo solucionar estos problemas?


Debe definir una ruta en su routes.rb que debe manejar la ruta de products/tags . Puedes definirlo así:

get "products/tags" => "products#tags", :as => :tags

Por lo tanto, debería darle un helper tags_path que debería evaluar a /products/tags . Esto debería eliminar los errores que mencionaste en la pregunta. Asegúrese de agregar esta ruta antes de definir los resources :product in your routes.rb

Ahora en actua-como-etiquetable-on , no he usado esta gema, pero deberías mirar el método all_tag_counts documentación . Su método ProductsController#tags necesitará algunos cambios en las siguientes líneas. No estoy seguro de si es exactamente lo que se requeriría, ya que uso Mongoid y no puedo probarlo.

def tags @tags = Product.all_tag_counts.(:conditions => ["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", "%#{params[:q]}%"]) respond_to do |format| format.json { render :json => @tags.collect{|t| {:id => t.name, :name => t.name } } end end


pequeño complemento:

Si desea crear las etiquetas sobre la marcha, puede hacer esto en su controlador:

def tags query = params[:q] if query[-1,1] == " " query = query.gsub(" ", "") Tag.find_or_create_by_name(query) end #Do the search in memory for better performance @tags = ActsAsTaggableOn::Tag.all @tags = @tags.select { |v| v.name =~ /#{query}/i } respond_to do |format| format.json{ render :json => @tags.map(&:attributes) } end end

Esto creará la etiqueta, siempre que se golpee la barra espaciadora.

A continuación, puede agregar esta configuración de búsqueda en el script jquery:

noResultsText: ''No result, hit space to create a new tag'',

Está un poco sucio pero funciona para mí.


Tuve problemas para editar las etiquetas si, por ejemplo, el modelo no pudo validar,

Cambié

<%= p.text_field :tag_list, :id => "product_tags", "data-pre" => @product.tags.map(&:attributes).to_json %>

a

<%= p.text_field :tag_list, :id => "product_tags", "data-pre" => @product.tag_list.map {|tag| {:id => tag, :name => tag } }.to_json %>

Si el formulario no se pudo validar en la primera presentación, estaba creando etiquetas como ID de las etiquetas que había creado en presentaciones posteriores.


Hay un error en el código Application.js. Hay un extra) después de "/products/tags.json". Eliminar el extra). El código debería ser:

$("#product_tags").tokenInput("/products/tags.json", { prePopulate: $("#product_tags").data("pre"), preventDuplicates: true, noResultsText: "No results, needs to be created.", animateDropdown: false });


Dos notas: si obtiene las etiquetas modificadas por números en la solicitud POST, use:

tokenValue: "name"

Y si intenta agregar etiquetas que no existen, use (no documentado):

allowFreeTagging: true