I would like to uniquely use owner tags in my app. My problem is that when I create / update a post via a form I only have f.text_field :tag_list
which only updates the tags for the post but has no owner. If I use f.text_field :all_tags_list
it doesn't know the attribute on create / update. I could add in my controller:
User.find(:first).tag( @post, :with => params[:post][:tag_list], :on => :tags )
but then I have duplicate tags, for post and for the owner tags. How can I just work with owner tags?
Try using delegation:
So when you save your posts it sets the tag on the user object directly.
the set_tag_owner before_save worked for me. But as bcb mentioned, I had to add a condition (tag_list_changed?) to prevent the tags from being deleted on update:
When working with ownership the taggable model gets its tags a little different. Without ownership it can get its tags like so:
However, both of these opperations create
taggins
, whosetagger_id
andtagger_type
arenil
.In order to have these fields set, you have to use this method:
Suppose you add this line to the
create/update
actions of yourPhotosController
:This will create two taggings (one with and one without
tagger_id/_type
), becauseparams[:photo][:tag_list]
is already included inphoto_params
. So in order to avoid that, just do not whitelist:tag_list
.For Rails 3 - remove
:tag_list
fromattr_accessible
.For Rails 4 - remove
:tag_list
fromparams.require(:photo).permit(:tag_list)
.At the end your
create
action might look like this:Also note that when tagging objects this way you cannot use the usual
tag_list
method to retrieve the tags of a photo, because it searches fortaggings
, wheretagger_id IS NULL
. You have to use insteadIn case your taggable object
belongs_to
a single user you can also userall_tags_list
.Late to the party, but I found guillaume06's solution worked well, and I added some additional functionality to it:
What this will enable: You will be able to specify the tag owner by the name of the relationship between the tagged model and the tag owner model.
How: write a module and include in your lib on initialization (
require 'lib/path/to/tagger'
):Usage Instructions:
I ended up creating a virtual attribute that runs the
User.tag
statement:In my
thing.rb
Model:The only thing you have to do is then change your views and controllers to update the
tag_list
totags
and make sure you set theuser_id
of thething
before thetags
of thething
.I used an observer to solve this. Something like:
in /app/models/tagging_observer.rb
Don't forget to declare your observer in application.rb