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