这是您使用jQuery Tokeninput和ActsAsTaggableOn自动填充功能的方法。
在我的情况下,我使用的是嵌套表格但不重要。以下所有内容都是有效的代码。
产品型号:
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 %>
必须有一行:
format.json { render :json => @tags.collect{|t| {:id => t.name, :name => t.name }}}
注意 - 您也可以在此处使用@tags.map
,也无需更改表单。
以下是您需要执行此操作的两个问题:
我有以下Tag
:{"id":1,"name":"Food"}
。当我保存标记为Product
的{{1}}时,它应在搜索时保存为"Food"
并找到名称ID: 1
。目前,它会使用引用"Food"
ID的新ID(即Tag
)保存新的"Food"
。相反,它应该是找到ID,显示名称,然后执行{"id":19,"name":"1"}
,这样就不会创建新的find_or_create_by
。
当我通过Tag
转到products/show
看标签时。该名称显示为“标签:1 ”,当它真的应该是“标签:食物”时。
如何解决这些问题?
答案 0 :(得分:4)
您应该在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
documentation。您的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
答案 1 :(得分: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
});
答案 2 :(得分: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',
它有点脏,但对我有用。
答案 3 :(得分:1)
我不知道这是否是您的错误的全部内容,但您没有使用tokenInput插件访问正确的URL。
此
$("#product_tag_list").tokenInput("/products/tags.json"), {
应该是
$("#product_tag_list").tokenInput("/products.json"), {
正如我所说,我不知道这是否是您遇到的唯一问题,但如果您更改此问题,是否有效?
编辑:
我从未使用ActsAsTaggableOn
。它是否为您创建Tag
模型?
从github上的外观来看,如果您想查询所有标记,则可能必须使用其命名空间而不仅仅是Tag
,这意味着{{ 1}}。例如,您可以看到他们如何直接访问某些the specs中的ActsAsTaggableOn::Tag
。
答案 4 :(得分: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。
答案 5 :(得分:1)
两个注意事项:如果您在POST请求中使用数字更改了标签,请使用:
tokenValue: "name"
如果您尝试添加不存在的标签,请使用(未记录的):
allowFreeTagging: true