How to Get a List of All Tags While Using the Gem 'Acts-As-Taggable-On' in Rails (Not the Counts)

How to get a list of all tags while using the gem 'acts-as-taggable-on' in Rails (not the counts)

The tags are stored in the Tags table, which you access from your program with e.g.

ActsAsTaggableOn::Tag.all

If you need more info on tag usage, there is also the table

ActsAsTaggableOn::Tagging

which contains links to where each tag is being used, including its context

To further apply this to your example, you can use

ActsAsTaggableOn::Tagging.includes(:tag).where(context: 'deshanatags').map { |tagging| { 'id' => tagging.tag_id.to_s, 'name' => tagging.tag.name } }.uniq

Let's explain the various parts in this statement:

  • the 'includes' makes sure the different tags are "eager loaded", in other words, that instead of loading n+1 records, only 2 queries will be done on the database
  • the 'where' limits the records to the ones with the given context
  • the 'map' converts the resulting array of records into a new array, containing the hashes you asked for in your problem, with id mapped to the tag's id, and name mapped to the tag's name
  • finally the 'uniq' makes sure that you don't have doubles in your list

To also cope with your additional problem, being taggins without tag, you could extend the where clause to

where("(context = 'deshanatags') AND (tag_id IS NOT NULL)")

How to get *ALL* tags on an acts_as_taggable object regardless of its contexts

c.base_tags.map(&:name)

There is no built-in shortcut to get the names directly, but that's short enough :)

Edit: base_tags is an association defined on classes declared as taggable: has_many :base_tags, through: :taggings, source: :tag, class_name: '::ActsAsTaggableOn::Tag'

Source: https://github.com/mbleigh/acts-as-taggable-on/blob/master/lib/acts_as_taggable_on/taggable.rb

How to count the amount of times a tag has been used with ActsAsTaggableOn rails

According to this and this, you should be able to:

Post.tag_counts

Given :tags is the "context" you used on the Post model.

Listing all tags for an acts_as_taggable

You dont need to go through all the trouble of creating a tag model and controller. `acts-as-taggable-on provides a method to find a list of all tags for the model.

2.0.0-p451 :008 > Factoid.tag_counts
ActsAsTaggableOn::Tag Load (2.0ms) SELECT tags.*, taggings.tags_count AS count FROM "tags" JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count FROM "taggings" INNER JOIN factoids ON factoids.id = taggings.taggable_id WHERE (taggings.taggable_type = 'Factoid' AND taggings.context = 'tags') AND (taggings.taggable_id IN(SELECT factoids.id FROM "factoids")) GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0) AS taggings ON taggings.tag_id = tags.id
=> #<ActiveRecord::Relation [#<ActsAsTaggableOn::Tag id: 1, name: "tag">]>

This will return a ActiveRecord::Relation of all the tag objects. You can run map on it to get a array of tags

Factoid.tag_counts.map(&:name)
=> ["tag"]

Return all tags based on context - ActsAsTaggableOn

I have never used acts-as-taggable-on but a quick browse through of the code suggests, you can do:

# to get all the tags with context topic with counts
ActsAsTaggableOn::Tagging.
includes(:tag).
where(:context => "topics").
group("tags.name").
select("tags.name, COUNT(*) as count")

You should probably take a look at ActsAsTaggableOn::Tagging, ActsAsTaggableOn::Tag and the migration file in your db/migrations folder to figure out how you can go about it.

If you don't want the count, only the tag names:

tags = ActsAsTaggableOn::Tag.includes(:taggings).
where("taggings.context = 'topics'").
select("DISTINCT tags.*")

# usage
tags.each {|tag| puts tag.name}

I hope that answers your question.

Acts-as-taggable-on find all tags by context

You could also use a statement like the following:

# Returns all the tags for the specified model/context with a count >= 1
@tags = YourModel.tag_counts_on(**context**)

Add limit and order:

# Get the top 5 tags by count
@tags = YourModel.tag_counts_on(**context**, :limit => 5, :order => "count desc")

Access the counts with the count attribute of the tags returned from tag_counts_on

tag.count

how to find number of tag matches in acts as taggable on

You can call tag_list on the objects and use that to figure out how many tags there are:

tags = %w{hello world planet earth}
objs = ModelName.taggedWith(tags, :any => true)
objs.sort_by! { |o| -(tags & o.tag_list).length }

The tags & o.tag_list yields the intersection of the tags you're looking for and the tags found, then we negate the size of the intersection to tell sort_by (which sorts in ascending order) to put larger intersections at the front, negating the result is an easy way to reverse the usual sort order.



Related Topics



Leave a reply



Submit