如何获取所有标签的列表,同时在Rails中使用gem“acts-as-taggable-on”(不包括计数)

时间:2022-05-08 02:43:24

I have set the acts-as-taggable-on gem in my model like this :

我在我的模型中设置了acts-as-taggable-on gem如下:

 acts_as_taggable_on :deshanatags

It use the context deshanatags. Now I need to get a list of all the tags (not only the ones assigned for one item. I need everything) in this context in the following format :

它使用了上下文deshanatags。现在我需要得到所有标签的列表(不仅仅是为一个项目分配的标签)。我需要一切)在这个上下文中以以下格式:

[
    {"id":"856","name":"House"},
    {"id":"1035","name":"Desperate Housewives"}
]

How can I do this?

我该怎么做呢?

I tried to follow many tutorials but hit dead ends because most of them are written for Rails 3. Rails for have some changes to the model like removal of attr_accessor which make it difficult for me to understand those tutorials. So please help.

我尝试遵循许多教程,但遇到了死胡同,因为大多数教程都是为Rails 3编写的。Rails for对模型做了一些更改,比如删除attr_accessor,这让我很难理解这些教程。所以请帮助。

Simply im trying to add Jquery Token input (http://loopj.com/jquery-tokeninput/) to my app

我只是想在我的应用程序中添加Jquery令牌输入(http://loopj.com/jquery-tokeninput/)

PS : Through Tagging table, is there a way to get a list of tags like the output of Tag.all by filtering the context?

PS:通过标签表,是否有办法得到一个标签列表,比如标签的输出。都是通过过滤上下文吗?

3 个解决方案

#1


35  

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

这些标签存储在tags表中,您可以从程序中访问这些标签。

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
  • “include”确保不同的标记是“急切加载的”,换句话说,不加载n+1记录,只在数据库上执行两个查询。
  • the 'where' limits the records to the ones with the given context
  • “where”将记录限制在给定的上下文中。
  • 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
  • “map”将生成的记录数组转换为一个新的数组,其中包含您在问题中要求的散列,id映射到标记的id,名称映射到标记的名称
  • finally the 'uniq' makes sure that you don't have doubles in your list
  • 最后,“uniq”确保你的列表中没有双打

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

为了解决您的附加问题,您可以将where子句扩展为无标记的taggins

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

#2


4  

I personally think that both solutions will be slow if you have many tags to retrieve as there are many single select statements. I'd do it like this:

我个人认为,如果您有许多标记可以检索,那么这两种解决方案都将是缓慢的,因为有许多单独的select语句。我会这样做:

ActsAsTaggableOn::Tagging.includes(:tag).where(context: 'deshanatags').uniq.pluck(:id, :name)

If you're on ruby 1.9+

如果你在ruby 1.9+上。

This way you'll just end up with:

这样你就会得到:

SELECT DISTINCT "taggings"."id", name FROM "taggings" LEFT OUTER JOIN "tags" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."context" = 'deshanatags'

Quick and easy imo

快速便捷的国际海事组织

#3


2  

Using the ActsAsTaggableOn::Tagging model, you can get a list of all tags and filter them down according to context, then format them as follows:

使用ActsAsTaggableOn::::标签模型,您可以得到所有标签的列表,并根据上下文对其进行过滤,然后格式化如下:

ActsAsTaggableOn::Tagging.all
.where(context: "deshanatags")
.map {|tagging| { "id" => "#{tagging.tag.id}", "name" => tagging.tag.name } }

The where will give us a result of all taggings for a given context, which we then iterate over using map, retrieving the related tag for each tagging in our result and getting the id and name attributes.

where将给出给定上下文的所有标记的结果,然后我们使用map进行迭代,检索结果中的每个标记的相关标记,并获取id和名称属性。

Make sure to chain the methods directly (not across several lines) if you're not using ruby 1.9+

如果不使用ruby 1.9+,请确保直接链接这些方法(不跨几行)

You can then call .to_json on the result to get a properly formatted json object that you can use

然后,您可以在结果上调用.to_json来获得一个可以使用的格式正确的json对象

edit:

I updated the post to clarify what each statement does and also updated the format of our final result to use strings as keys instead of symbols

我更新了这篇文章,以阐明每个语句的作用,并更新了最终结果的格式,使用字符串作为键,而不是符号

#1


35  

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

这些标签存储在tags表中,您可以从程序中访问这些标签。

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
  • “include”确保不同的标记是“急切加载的”,换句话说,不加载n+1记录,只在数据库上执行两个查询。
  • the 'where' limits the records to the ones with the given context
  • “where”将记录限制在给定的上下文中。
  • 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
  • “map”将生成的记录数组转换为一个新的数组,其中包含您在问题中要求的散列,id映射到标记的id,名称映射到标记的名称
  • finally the 'uniq' makes sure that you don't have doubles in your list
  • 最后,“uniq”确保你的列表中没有双打

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

为了解决您的附加问题,您可以将where子句扩展为无标记的taggins

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

#2


4  

I personally think that both solutions will be slow if you have many tags to retrieve as there are many single select statements. I'd do it like this:

我个人认为,如果您有许多标记可以检索,那么这两种解决方案都将是缓慢的,因为有许多单独的select语句。我会这样做:

ActsAsTaggableOn::Tagging.includes(:tag).where(context: 'deshanatags').uniq.pluck(:id, :name)

If you're on ruby 1.9+

如果你在ruby 1.9+上。

This way you'll just end up with:

这样你就会得到:

SELECT DISTINCT "taggings"."id", name FROM "taggings" LEFT OUTER JOIN "tags" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."context" = 'deshanatags'

Quick and easy imo

快速便捷的国际海事组织

#3


2  

Using the ActsAsTaggableOn::Tagging model, you can get a list of all tags and filter them down according to context, then format them as follows:

使用ActsAsTaggableOn::::标签模型,您可以得到所有标签的列表,并根据上下文对其进行过滤,然后格式化如下:

ActsAsTaggableOn::Tagging.all
.where(context: "deshanatags")
.map {|tagging| { "id" => "#{tagging.tag.id}", "name" => tagging.tag.name } }

The where will give us a result of all taggings for a given context, which we then iterate over using map, retrieving the related tag for each tagging in our result and getting the id and name attributes.

where将给出给定上下文的所有标记的结果,然后我们使用map进行迭代,检索结果中的每个标记的相关标记,并获取id和名称属性。

Make sure to chain the methods directly (not across several lines) if you're not using ruby 1.9+

如果不使用ruby 1.9+,请确保直接链接这些方法(不跨几行)

You can then call .to_json on the result to get a properly formatted json object that you can use

然后,您可以在结果上调用.to_json来获得一个可以使用的格式正确的json对象

edit:

I updated the post to clarify what each statement does and also updated the format of our final result to use strings as keys instead of symbols

我更新了这篇文章,以阐明每个语句的作用,并更新了最终结果的格式,使用字符串作为键,而不是符号