【问题标题】:How to use jquery-Tokeninput and Acts-as-taggable-on如何使用 jquery-Tokeninput 和 Acts-as-taggable-on
【发布时间】:2011-07-13 04:34:09
【问题描述】:

这就是您如何使用 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

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
  });
});

表格:

<%= 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,您也不必更改表单。

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

我有以下Tag{"id":1,"name":"Food"}。当我保存Product,标记为"Food" 时,它应该在搜索并找到名称"Food" 时保存为ID: 1。目前,它使用引用"Food" ID 的新ID 保存新的Tag,即{"id":19,"name":"1"}。相反,它应该查找 ID、显示名称并执行 find_or_create_by,因此它不会创建新的 Tag


问题 2(已解决)


当我通过&lt;%= @product.tag_list %&gt;products/show 查看标签时。名称显示为“Tags: 1”,而实际上应该是“Tags: Food”。

如何解决这些问题?

【问题讨论】:

  • 您能否从rake routes 的输出中添加相关部分。似乎您因路线而面临一些问题。
  • 我能想到的关于我的路线的唯一相关部分是 new_product GET /products/new(.:format) {:action=>"new", :controller=>"products"},我编辑了我的答案并包含了我所有的产品路线。
  • 你能发布你的控制器方法来接受来自标签表单的数据吗?
  • 我没有标签表单吗?你的意思是我的 ProductsController 新方法和创建方法,如果是这样,我会将它们发布到。标记方法已经启动。
  • 问题是采取输入将 id 列表提交回服务器而不是名称,并且看起来像 act-as-taggable 直接与名称一起使用。查看已编辑的tags 回答中的操作。

标签: ruby-on-rails ruby ruby-on-rails-3 autocomplete acts-as-taggable-on


【解决方案1】:

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

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

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

现在到acts-as-taggable-on,我没有使用过这个gem,但你应该看看方法all_tag_countsdocumentation。您的 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

【讨论】:

  • 看看我的 2.Note,链接gist.github.com/988968,第三个要点框。我到底要去哪里? 必须路由到我的 def 标签,但我不知道如何以及我称之为路径。
  • 看看gist.github.com/1090097,在定义路由后(第4个文件)你应该可以用products_tags_path替换example_get_all_tags_path
  • 谢谢,让这项工作几乎完成,但他们仍然有 2 个问题。现在看看我的问题,我编辑了整件事。
  • 好的,你得到了它的工作,我感谢所有的帮助,我会在这几天。我在这里学到了很多,因为我是 Ruby 和 Rails 的新手,谢谢。
  • 不确定我是否应该劫持这个线程,所以没有。我也很难实施这个解决方案,可以使用一些帮助! stackoverflow.com/questions/8214155/…
【解决方案2】:

小插件:

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

 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',

它有点脏,但对我有用。

【讨论】:

  • 我也喜欢 noResultsText。感谢您的意见。
  • 有点晚了,但不是 Tag.find... 应该是 ActsAsTaggableOn::Tag.find_or_create...,无论如何,它对我有用,谢谢!
【解决方案3】:

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
});

【讨论】:

    【解决方案4】:

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

    这个

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

    应该是

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

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

    编辑:

    我从未使用过ActsAsTaggableOn。它会创建一个Tag 模型供您使用吗?

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

    【讨论】:

    • 是的,这就是我遇到的问题。我确定是否可以使此页面正常工作,然后我将 Tokeninput 映射到正确的位置。我相信您在此处输入的内容会起作用,但我认为我的控制器代码有误,因此无法正常工作。
    • 你能发布products.json的输出吗?
    • 根据您提供的信息进一步编辑了我的答案。
    【解决方案5】:

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

    我变了

    <%= 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。

    【讨论】:

      【解决方案6】:

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

      tokenValue:        "name"
      

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

      allowFreeTagging:  true
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多