2

我有一個RoR應用程序,允許用戶標記他們的集合中的項目。我使用tag-it.js Jquery插件並使用Ajax調用來添加和刪除ItemsController中的標籤。我的問題是每個標籤都添加了兩次,這樣當我執行@ item.tags.each時,所有標籤都會顯示兩次。acts_as_taggable_on標籤添加兩次

上述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 

的Javascript處理該AJAX標籤與標籤-it.js:當用戶添加/刪除標籤

$('#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); 
      } 
     })   
     } 
}); 

項目#_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/<%[email protected] %>/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()方法似乎覆蓋了以前的項目標記,所以我必須將新標記添加到以前的標記才能保留它們。

此外,當我提交物品#_form時,我需要以某種方式讓update方法忽略tags屬性,因爲它試圖將它們保存到該項目,但它們已經保存在AJAX調用中,所以出現此錯誤:

ActiveRecord::AssociationTypeMismatch in ItemsController#update 
ActsAsTaggableOn::Tag(#82082080) expected, got String(#72294010) 

在此先感謝。

PS。這裏是我得到了在上述ItemsController自動完成的工作:

def get_autocomplete_items(parameters) 
    tags = current_user.owned_tags.named_like(parameters[:term]) 
end 
+0

嗯...當我接着說:profile.tag_list.add( 「鮑勃」)'我的控制器代碼,因爲你有我的問題開始。我認爲這條線是不必要的。沒有它,我只能得到一個標籤。有了它,我得到了重複。 – Ziggy

回答

0

小心與網頁負載點火onTagAdded事件。看到這裏事件樣本http://aehlke.github.com/tag-it/examples.html

//------------------------------- 
// Tag events 
//------------------------------- 
var eventTags = $('#eventTags'); 
eventTags.tagit({ 
    availableTags: sampleTags, 
    onTagRemoved: function(evt, tag) { 
     console.log(evt); 
     alert('This tag is being removed: ' + eventTags.tagit('tagLabel', tag)); 
    }, 
    onTagClicked: function(evt, tag) { 
     console.log(tag); 
     alert('This tag was clicked: ' + eventTags.tagit('tagLabel', tag)); 
    } 
}).tagit('option', 'onTagAdded', function(evt, tag) { 
    // Add this callbackafter we initialize the widget, 
    // so that onTagAdded doesn't get called on page load. 
    alert('This tag is being added: ' + eventTags.tagit('tagLabel', tag)); 
}); 
0

你是對的:

與給定的名單

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.

.tag方法過度寫入現有標記。因此,如果您想添加新標籤,您似乎需要將新標籤追加到現有標籤,然後傳入新列表。但是,.tag_list.add實際上也會創建標籤。

所以,當你這樣做:

@item.tag_list.add(params[:tag]) 
    current_user.tag(@item, :with => @item.tag_list.to_s, :on => :tags)   

你的確被加入新的標籤的兩倍。

當我這樣做:

tag_list = profile.tag_list // oops! 
tag_list.add(tags) 
self.tag(profile, with: tag_list, on: :tags) 

我創建的tag_list的引用,然後調用添加就可以了。我們需要做的是這樣的:

tag_list = profile.tags.map(&:name) 

爲我們標記的對象創建一個數組標籤名稱。然後我們可以調用添加列表的副本,沒問題!沒有更多重複的標籤。

我很高興我遇到了你的問題,因爲它使我對我有效。不過,如果圖書館提供這樣一個好方法,我會更加高興。通過閱讀文檔,我無法找到一個好方法。

+0

哈哈,不,這仍然覆蓋現有的標籤......堅持我正在努力! – Ziggy

+0

好了,現在可以使用了。 – Ziggy

0

你做得很好,但只是一個小小的錯誤。

這裏tag_list越來越重複的標籤,一個與業主沒有業主

@item.tag_list.add(params[:tag])線添加標籤沒有業主

而且current_user.tag(@item, :with => @item.tag_list.to_s, :on => :tags)線將相同的標籤具有所有者

而後來,當您保存對象時,因爲tag_list的表現爲參照未ownered對象標籤,都得到保存

下面的代碼將正常工作。

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