7

我想在我的应用程序中唯一地使用所有者标签。我的问题是,当我通过表单创建/更新帖子时,我f.text_field :tag_list只有更新帖子标签但没有所有者的表单。如果我使用f.text_field :all_tags_list它不知道创建/更新的属性。我可以在我的控制器中添加:

User.find(:first).tag( @post, :with => params[:post][:tag_list], :on => :tags )

但后来我有重复的标签,用于发布和所有者标签。我怎样才能只使用所有者标签?

4

7 回答 7

4

https://github.com/mbleigh/acts-as-taggable-on/issues/111上的customersure(SO 上的tsdbrown)提出的答案对我有用

# In a taggable model:
before_save :set_tag_owner
def set_tag_owner
    # Set the owner of some tags based on the current tag_list
    set_owner_tag_list_on(account, :tags, self.tag_list)
    # Clear the list so we don't get duplicate taggings
    self.tag_list = nil
 end

# In the view:
<%= f.text_field :tag_list, :value => @obj.all_tags_list %>
于 2011-07-01T08:17:07.043 回答
2

我用观察者来解决这个问题。就像是:

在 /app/models/tagging_observer.rb

class TaggingObserver < ActiveRecord::Observer
  observe ActsAsTaggableOn::Tagging

  def before_save(tagging)
    tagging.tagger = tagging.taggable.user if (tagging.taggable.respond_to?(:user) and tagging.tagger != tagging.taggable.user)
  end
end

不要忘记在 application.rb 中声明你的观察者

config.active_record.observers = :tagging_observer
于 2011-09-13T08:09:34.503 回答
1

聚会迟到了,但我发现 guillaume06 的解决方案效果很好,我添加了一些额外的功能:

这将启用什么:您将能够通过标记模型和标记所有者模型之间的关系名称来指定标记所有者。

如何:编写一个模块并在初始化时包含在您的库中(require 'lib/path/to/tagger'):

  module Giga::Tagger
    extend ActiveSupport::Concern
    included do
      def self.tagger owner
        before_save :set_tag_owner
        def set_tag_owner
          self.tag_types.each do |tag|
            tag_type = tag.to_s
            # Set the owner of some tags based on the current tag_list
            set_owner_tag_list_on(owner, :"#{tag_type}", self.send(:"#{tag_type.chop}_list"))
            # Clear the list so we don't get duplicate taggings
            self.send(:"#{tag_type.chop}_list=",nil)
          end
        end

      end
    end
  end

使用说明:

  Given: A model, Post, that is taggable
         A model, User, that is the tag owner
         A post is owned by the user through a relationship called :owner
  Then add to Post.rb:
         include Tagger
         acts_as_taggable_on :skills, :interests, :tags
         tagger :owner
  Make sure Post.rb already has called acts_as_taggable_on, and that User.rb has acts_as_tagger
  Note: This supports multiple tag contexts, not just tags (eg skills, interests)..
于 2013-07-09T10:52:27.933 回答
1

set_tag_owner before_save 为我工作。但正如 bcb 提到的,我必须添加一个条件 (tag_list_changed?) 以防止标签在更新时被删除:

def set_tag_owner
  if tag_list_changed?
    set_owner_tag_list_on(account, :tags, tag_list)
    self.tag_list = nil
  end
end
于 2014-07-29T14:59:18.337 回答
1

当使用所有权时,可标记模型的标签会有所不同。如果没有所有权,它可以像这样获得它的标签:

@photo.tag_list << 'a tag' # adds a tag to the existing list
@photo.tag_list = 'a tag' # sets 'a tag' to be the tag of the @post

但是,这两个操作都创建taggins, whotagger_idtagger_typeare nil

为了设置这些字段,您必须使用此方法:

@user.tag(@photo, on: :tags, with: 'a tag')

假设您将此行添加到create/update您的操作中PhotosController

@user.tag(@photo, on: :tags, with: params[:photo][:tag_list])

这将创建两个标记(一个带有,一个不带tagger_id/_type),因为params[:photo][:tag_list]已经包含在photo_params. 因此,为了避免这种情况,请不要将其列入白名单:tag_list

对于 Rails 3 -:tag_listattr_accessible.

对于 Rails 4 -:tag_listparams.require(:photo).permit(:tag_list).

最后,您的create操作可能如下所示:

def create
  @photo = Photo.new(photo_params) # at this point @photo will not have any tags, because :tag_list is not whitelisted
  current_user.tag(@photo, on: :tags, with: params[:photo][:tag_list])

  if @photo.save
    redirect_to @photo
  else
    render :new
  end
end

另请注意,以这种方式标记对象时,您不能使用通常的tag_list方法来检索照片的标签,因为它会搜索taggings, where tagger_id IS NULL。你必须改用

@photo.tags_from(@user)

如果您的可标记对象belongs_to是单个用户,您也可以使用 user all_tags_list

于 2015-07-28T21:34:18.643 回答
0

尝试使用委托:

class User < ActiveRecord::Base
  acts_as_taggable_on
end

class Post < ActiveRecord::Base
  delegate :tag_list, :tag_list=, :to => :user
end

因此,当您保存帖子时,它会直接在用户对象上设置标签。

于 2011-02-01T18:01:50.060 回答
0

我最终创建了一个运行User.tag语句的虚拟属性:

在我的thing.rb模型中:

attr_accessible :tags
belongs_to :user
acts_as_taggable

def tags
    self.all_tags_list
end

def tags=(tags)
    user = User.find(self.user_id)
    user.tag(self, :with => tags, :on => :tags, :skip_save => true)
end

您唯一需要做的就是更改您的视图和控制器以更新totag_list并确保tagsuser_id在.thingtagsthing

于 2013-03-30T18:21:21.873 回答