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

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

  acts_as_taggable_on :deshanatags 

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

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

我怎样才能做到这一点?

我试图遵循许多教程但是达到了死胡同,因为它们大部分都是为Rails编写的.Rails对模型进行了一些更改,比如删除了attr_accessor,这让我很难理解这些教程。 所以请帮忙。

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

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

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

 ActsAsTaggableOn::Tag.all 

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

 ActsAsTaggableOn::Tagging 

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

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

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

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

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

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

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

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

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

如果你使用ruby 1.9+

这样你最终会得到:

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

快速简单的imo

使用ActsAsTaggableOn::Tagging模型,您可以获取所有标记的列表并根据上下文过滤它们,然后按如下格式进行格式化:

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

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

如果你没有使用ruby 1.9+,请确保直接链接方法(不是跨多行)

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

编辑:

我更新了post以澄清每个语句的作用,并更新了我们最终结果的格式,以便将字符串用作键而不是符号