actions_as_taggable_on标签已添加两次 [英] acts_as_taggable_on Tags added twice
问题描述
我有一个RoR应用程序,允许用户标记其收藏夹中的项目.我使用tag-it.js Jquery插件,并使用Ajax调用在ItemsController中添加和删除标签.我的问题是每个标签都添加了两次,所以当我执行@ item.tags.each时,所有标签都显示两次.
I have a RoR app that allows users to tag items in their collections. I use the tag-it.js Jquery plugin and use Ajax calls to add and remove the tags in the ItemsController. My problem is that each tag is added twice so that when I do @item.tags.each, all the tags are shown twice.
ItemsController:
def add_tag
@collection = current_user.collections.find(params[:collection_id])
@item = @collection.items.find(params[:id])
@item.tag_list.add(params[:tag])
current_user.tag(@item, :with => @item.tag_list.to_s, :on => :tags)
@item.save
render nothing: true
end
def remove_tag
@item = current_user.items.find_by_id(params[:id])
@item.tag_list.remove(params[:tag])
current_user.tag(@item, :with => @item.tag_list.to_s, :on => :tags)
@item.save
render nothing: true
end
使用Tag-it.js处理AJAX标记的Javascript:
$('#item_tags').tagit({
onTagAdded: function(event, tag) {
var add_url = $('#item_tags').attr("data-add-url");
$.ajax({
url: add_url,
data: {tag: tag.text().substring(0, tag.text().length-1)},
})
},
onTagRemoved: function(event, tag) {
var remove_url = $('#item_tags').attr("data-remove-url");
$.ajax({
url: remove_url,
type: 'DELETE',
data: {tag: tag.text().substring(0, tag.text().length-1)},
})
},
tagSource: function(search, showChoices) {
var autocomplete_url = $('#item_tags').attr("data-auctocomplete-url");
$.ajax({
url: autocomplete_url,
data: {term: search.term},
success: function(choices) {
showChoices(choices);
}
})
}
});
item#_form用户在其中添加/删除标签的视图:
<ul id='item_tags' class='tagit' data-remove-url="<%= remove_tag_collection_item_path %>" data-add-url="<%= add_tag_collection_item_path %>" data-auctocomplete-url="/collections/<%=@collection.id %>/items/autocomplete_tag_name">
<% @item.tags.each do |tag| %>
<li><%= tag.name %></li>
<% end %>
</ul>
我必须注意,有必要拥有标签所有权(由current_user拥有),以便Jquery自动完成仅基于当前用户的先前标签而不是所有用户完成.我认为问题是我必须将标签添加到tag_list,然后将tag_list添加到用户项标签.我找不到解决方法,因为在调用current_user.tag()时current_user.tag()方法似乎会覆盖先前的项目标签,因此我必须将新标签添加到先前的标签中以保留它们.
I must note that it is necessary to have tag ownership (by current_user) so that the Jquery auto complete only completes based on current user's previous tags and not all users. I think the problem is that I have to add the tag to the tag_list and then add the tag_list to the user item tagging. I can't find a way around this because the current_user.tag() method seems to overwrite the previous item tags when current_user.tag() is called so I have to add the new tag to the previous tags to preserve them.
另外,当我提交item#_form时,我需要以某种方式让update方法忽略标签属性,因为它试图将它们保存到该项目中,但是它们已经通过AJAX调用保存了,所以出现此错误:
Additionally when I submit the item#_form, I need to somehow have the update method ignore the tags attribute because it's trying to save them to the item but they're already saved with an AJAX call so I get this error:
ActiveRecord::AssociationTypeMismatch in ItemsController#update
ActsAsTaggableOn::Tag(#82082080) expected, got String(#72294010)
先谢谢了.
PS.这是我如何在ItemsController中完成自动完成的工作:
PS. Here is how I got the auto complete working in the ItemsController:
def get_autocomplete_items(parameters)
tags = current_user.owned_tags.named_like(parameters[:term])
end
推荐答案
您没事,但是,只有一个小错误.
You were doing all right, but, just one little mistake.
此处tag_list
正在获取重复的标签,一个带有所有者,而另一个没有所有者
Here tag_list
is getting duplicate tags, one with Owner and other without Owner
您的@item.tag_list.add(params[:tag])
行正在添加标签没有所有者
并且current_user.tag(@item, :with => @item.tag_list.to_s, :on => :tags)
行添加了与所有者
And current_user.tag(@item, :with => @item.tag_list.to_s, :on => :tags)
line is adding same tag with Owner
后来,当您保存对象时,由于tag_list
表现为对对象的无人标签的引用,因此两者都被保存了
And later, when you save the object, since tag_list
is behaving as reference to un-ownered tags of object, both get saved
下面的代码应该可以正常工作.
Following code shall work fine.
def add_tag
@collection = current_user.collections.find(params[:collection_id])
@item = @collection.items.find(params[:id])
tag_list = @item.all_tag_list.dup # Reference to original tag_list avoided
# Also instead of "tag_list", use "all_tag_list" method, as "tag_list" only return tags without owner
# Link(go to last line og Tag Ownership topic) : "https://github.com/mbleigh/acts-as-taggable-on#tag-ownership"
tag_list.add(params[:tag])
current_user.tag(@item, :with => tag_list.to_s, :on => :tags)
@item.save
render nothing: true
end
def remove_tag
@item = current_user.items.find_by_id(params[:id])
tag_list = @item.all_tag_list.dup # Reference to original tag_list avoided
tag_list.remove(params[:tag])
current_user.tag(@item, :with => tag_list.to_s, :on => :tags)
@item.save
render nothing: true
end
改进版本
def add_owned_tag
@some_item = Item.find(params[:id])
owned_tag_list = @some_item.all_tag_list - @some_item.tag_list
owned_tag_list += [(params[:tag])]
@tag_owner.tag(@some_item, :with => stringify(owned_tag_list), :on => :tags)
@some_item.save
end
def stringify(tag_list)
tag_list.inject('') { |memo, tag| memo += (tag + ',') }[0..-1]
end
def remove_owned_tag
@some_item = Item.find(params[:id])
owned_tag_list = @some_item.all_tag_list - @some_item.tag_list
owned_tag_list -= [(params[:tag])]
@tag_owner.tag(@some_item, :with => stringify(owned_tag_list), :on => :tags)
@some_item.save
end
这篇关于actions_as_taggable_on标签已添加两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!