actions_as_taggable_on标签已添加两次 [英] acts_as_taggable_on Tags added twice

查看:103
本文介绍了actions_as_taggable_on标签已添加两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆