如何在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以澄清每个语句的作用,并更新了我们最终结果的格式,以便将字符串用作键而不是符号