如何在Rails中使用gem'atject-as-taggable-on'获取所有标签的列表(不是计数)

THp*_*ubs 17 ruby ruby-on-rails acts-as-taggable-on ruby-on-rails-4

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

 acts_as_taggable_on :deshanatags
Run Code Online (Sandbox Code Playgroud)

它使用上下文deshanatags.现在我需要在此上下文中以下列格式获取所有标记的列表(不仅是为一个项目分配的标记.我需要一切):

[
    {"id":"856","name":"House"},
    {"id":"1035","name":"Desperate Housewives"}
]
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

我试图按照很多教程,但命中死角,因为他们大多是为Rails编写3. Rails使用有一定的变化像去除attr_accessor这使我很难理解这些教程模式.所以请帮忙.

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

PS:通过标记表,有没有办法通过过滤上下文来获取像Tag.all输出的标签列表?

Dan*_*nny 36

标签存储在Tags表中,您可以从程序中使用例如

ActsAsTaggableOn::Tag.all
Run Code Online (Sandbox Code Playgroud)

如果您需要有关标签使用的更多信息,还有表格

ActsAsTaggableOn::Tagging
Run Code Online (Sandbox Code Playgroud)

其中包含指向每个标记使用位置的链接,包括其上下文

要进一步将此应用于您的示例,您可以使用

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

让我们解释一下这个陈述中的各个部分:

  • 'includes'确保不同的标签是"急切加载",换句话说,不是加载n + 1条记录,只对数据库进行2次查询
  • 'where'将记录限制为具有给定上下文的记录
  • 'map'将生成的记录数组转换为一个新数组,其中包含您在问题中要求的哈希值,id映射到标记的id,名称映射到标记的名称
  • 最后'uniq'确保你的列表中没有双打

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

where("(context = 'deshanatags') AND (tag_id IS NOT NULL)")
Run Code Online (Sandbox Code Playgroud)


Fab*_*sso 5

我个人认为,如果您有许多标签要检索,那么这两种解决方案都会很慢,因为有许多单个 select 语句。我会这样做:

ActsAsTaggableOn::Tagging.includes(:tag).where(context: 'deshanatags').uniq.pluck(:id, :name)
Run Code Online (Sandbox Code Playgroud)

如果你使用 ruby​​ 1.9+

这样你最终会得到:

SELECT DISTINCT "taggings"."id", name FROM "taggings" LEFT OUTER JOIN "tags" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."context" = 'deshanatags'
Run Code Online (Sandbox Code Playgroud)

快速简便的imo