2010-09-01 14 views
7

Tôi muốn sử dụng duy nhất thẻ của chủ sở hữu trong ứng dụng của mình. Vấn đề của tôi là khi tôi tạo/cập nhật một bài đăng thông qua biểu mẫu, tôi chỉ có f.text_field :tag_list chỉ cập nhật các thẻ cho bài đăng nhưng không có chủ sở hữu. Nếu tôi sử dụng f.text_field :all_tags_list, nó không biết thuộc tính khi tạo/cập nhật. Tôi có thể thêm vào bộ điều khiển của mình:Cập nhật thẻ của chủ sở hữu thông qua biểu mẫu

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

nhưng sau đó tôi có thẻ trùng lặp, cho bài đăng và thẻ của chủ sở hữu. Làm cách nào tôi có thể làm việc với thẻ của chủ sở hữu?

+0

Tôi đang cố gắng đạt được điều tương tự. Bạn đã nhận được bất cứ nơi nào với điều này? – tsdbrown

+0

Tôi đã hỏi về điều này trên github: http://github.com/mbleigh/acts-as-taggable-on/issues/issue/111/#issue/111 – tsdbrown

+1

Bạn có nghĩ về việc có mô hình owner_tags thuộc về Chủ sở hữu và bài đăng? Nó sẽ đòi hỏi một chút legwork hơn, nhưng sau đó bạn sẽ biết ai sở hữu các thẻ cũng như bài mà họ thuộc về. Bạn có thể cần phải có attr_accessor: tag_list để các dạng xem biểu mẫu vẫn hoạt động và sau đó lấy mô hình để tách chúng ra thành mô hình owner_tags khi tạo/udpate. – Adam21e

Trả lời

0

Hãy thử sử dụng đoàn:

class User < ActiveRecord::Base 
    acts_as_taggable_on 
end 

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

Vì vậy, khi bạn lưu bài viết của mình nó đặt thẻ trên đối tượng người dùng trực tiếp.

4

Câu trả lời bởi customersure đề xuất (tsdbrown trên SO) trên https://github.com/mbleigh/acts-as-taggable-on/issues/111 công trình đối với tôi

# 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 %> 
+0

Điều này dường như không hoạt động đối với tôi trong ví dụ này http://stackoverflow.com/questions/6933659/how-do-i-display-a-current-users-tags-tagged-with-acts-as- taggable-on – Simpleton

+2

Điều này làm việc tuyệt vời cho tôi. Tuy nhiên, hãy chắc chắn đặt điều kiện trên before_save trừ khi bạn thực sự muốn mã này được thực hiện trước khi lưu mọi thứ (ví dụ, khi lưu bên ngoài biểu mẫu). Ví dụ: nếu bạn cập nhật thuộc tính ở nơi khác trong mã của mình và các thuộc tính đó không bao gồm "tag_list", bạn sẽ bị đốt cháy (danh sách thẻ của chủ sở hữu sẽ được đặt thành vô tình). Tôi tìm thấy điều này ra tay đầu tiên :) – bcb

2

tôi đã sử dụng một người quan sát để giải quyết này. Một cái gì đó như:

trong /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 

Đừng quên khai báo quan sát của bạn trong application.rb

config.active_record.observers = :tagging_observer 
0

tôi đã kết thúc việc tạo ra một thuộc tính ảo chạy câu hỏi User.tag:

Trong số thing.rb của tôi Mẫu:

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 

Điều duy nhất bạn phải làm là sau đó thay đổi quan điểm và các bộ điều khiển của bạn để cập nhật các tag_list để tags và chắc chắn rằng bạn thiết lập user_id của thing trước tags của thing.

1

muộn để đảng, nhưng tôi tìm thấy giải pháp guillaume06 của làm việc tốt, và tôi đã thêm một số chức năng bổ sung với nó:

Điều này sẽ cho phép: Bạn sẽ có thể để xác định chủ sở hữu thẻ bằng tên của mối quan hệ giữa mô hình được gắn thẻ và mô hình chủ sở hữu thẻ.

Làm thế nào: viết một module và đưa vào lib của bạn trên khởi tạo (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 

Hướng dẫn sử dụng:

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).. 
1

các before_save set_tag_owner làm việc cho tôi. Nhưng khi bcb đã đề cập, tôi đã có thêm một điều kiện (tag_list_changed?) Để ngăn chặn các thẻ không bị xóa trên bản cập nhật:

def set_tag_owner 
    if tag_list_changed? 
    set_owner_tag_list_on(account, :tags, tag_list) 
    self.tag_list = nil 
    end 
end 
+0

Xin vui lòng chia sẻ mã của bạn, tôi không tìm thấy đây là một câu trả lời hợp lệ. – simeg

0

Khi làm việc với quyền sở hữu mô hình taggable được thẻ của nó hơi khác một chút.Nếu không có quyền sở hữu nó có thể nhận được thẻ của mình như sau:

@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 

Tuy nhiên, cả hai opperations tạo taggins, mà tagger_idtagger_typenil.

Để có các lĩnh vực này được thiết lập, bạn phải sử dụng phương pháp này:

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

Giả sử bạn thêm dòng này vào create/update hành động của PhotosController của bạn:

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

Điều này sẽ tạo ra hai gắn thẻ (một và không có tagger_id/_type), bởi vì params[:photo][:tag_list] đã được bao gồm trong photo_params. Vì vậy, để tránh điều đó, chỉ cần không ghi danh sách trắng :tag_list.

Đối với Rails 3 - loại bỏ :tag_list từ attr_accessible.

Đối với Rails 4 - loại bỏ :tag_list từ params.require(:photo).permit(:tag_list).

Cuối cùng hành động create của bạn có thể trông như thế này:

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 

Cũng lưu ý rằng khi gắn thẻ đối tượng bằng cách này bạn không thể sử dụng thông thường phương pháp tag_list để lấy thẻ của một bức ảnh, vì nó tìm kiếm taggings , trong đó tagger_id IS NULL. Bạn phải sử dụng thay vì

@photo.tags_from(@user) 

Trong trường hợp đối tượng taggable bạn belongs_to một người dùng duy nhất bạn cũng có thể sử dụng all_tags_list.