14

这就是您如何使用jQuery TokeninputActsAsTaggableOn的自动完成功能。

在我的情况下,我使用的是嵌套形式,但这并不重要。下面的所有内容都是有效的代码。

代码

产品型号:

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

产品控制器:

  #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

路线:

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

应用程序.js:

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

形式:

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

问题 1(已解决)


必须有以下行:

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

注意 - 您也可以@tags.map在此处使用,也不必更改表格。

以下是关于您为什么需要这样做的两个问题:

我有以下内容Tag{"id":1,"name":"Food"}。当我保存一个Product, 标记"Food"时,它应该保存为ID: 1当它搜索并找到名称时"Food"。目前,它Tag使用引用该ID 的新 ID 保存一个新"Food"ID,即{"id":19,"name":"1"}. 相反,它应该找到 ID,显示名称,然后这样做find_or_create_by,它不会创建新的Tag.


问题 2(已解决)


当我products/show通过做来查看标签时<%= @product.tag_list %>。该名称显示为“标签:1 ”,而实际上应该是“标签:食物”。

我该如何解决这些问题?

4

6 回答 6

5

您应该在routes.rb应该处理products/tags路径的路径中定义一个路由。您可以像这样定义它:

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

因此应该给你一个tags_path应该评估为的助手/products/tags。这应该消除您在问题中提到的错误。请务必在定义之前添加此resources :product路线routes.rb

现在进入acts-as-taggable-on,我没有使用过这个gem,但你应该看看方法all_tag_counts 文档。您的ProductsController#tags方法需要对以下几行进行一些更改。我不确定它是否正是需要的,因为我使用 Mongoid 并且无法对其进行测试。

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
于 2011-07-18T13:03:07.230 回答
4

Application.js 代码中有一个错误。在“/products/tags.json”之后有一个额外的 )。删除多余的)。代码应该是:

$("#product_tags").tokenInput("/products/tags.json", {
    prePopulate:       $("#product_tags").data("pre"),
    preventDuplicates: true,
    noResultsText:     "No results, needs to be created.",
    animateDropdown:   false
});
于 2011-10-15T08:59:03.617 回答
4

小插件:

如果要动态创建标签,可以在控制器中执行此操作:

 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

每当按下空格键时,这将创建标签。

然后,您可以在 jquery 脚本中添加此搜索设置:

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

它有点脏,但对我有用。

于 2011-11-23T00:11:09.320 回答
1

我不知道这是否是您的全部错误,但您没有使用 tokenInput 插件访问正确的 URL。

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

应该

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

正如我所说,我不知道这是否是您遇到的唯一问题,但是如果您更改此设置,它会起作用吗?

编辑:

我从来没有用过ActsAsTaggableOn。它是否创建了一个Tag模型供您使用?

从github上的外观来看,如果你想查询所有标签,你可能不得不使用它的命名空间,而不是仅仅Tag, 意思ActsAsTaggableOn::Tag。例如,您可以Tag在某些规范中看到他们如何直接访问 s 。

于 2011-07-13T17:16:14.893 回答
1

如果模型无法验证,我在编辑标签时遇到问题,

我变了

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

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

如果表单在第一次提交时验证失败,它正在创建标签作为它在后续提交中创建的标签的 ID。

于 2011-12-13T22:02:49.557 回答
1

两个注意事项:如果您在 POST 请求中通过数字更改标签,请使用:

tokenValue:        "name"

如果您尝试添加不存在的标签,请使用(未记录):

allowFreeTagging:  true
于 2013-10-20T18:43:39.587 回答