在Rails 3中标记会是一个很好的解决方案?在Rails 3中标记3
回答
我看着这两个解决方案,但更喜欢 https://github.com/mbleigh/acts-as-taggable-on 超过 https://github.com/jviney/acts_as_taggable_on_steroids
更好的文档和我来说,似乎更灵活。
act_as_taggable_on_steroids
https://github.com/bradphelan/rocket_tag
是我昨天刚刚创建了一个新的库。它使用Ernie Miller的squeel gem 实现,因此所有可怕的SQL都需要正确实现标签库 非常干净。
比较acts_as_taggable_ons
def tagged_with(tags, options = {})
tag_list = ActsAsTaggableOn::TagList.from(tags)
empty_result = scoped(:conditions => "1 = 0")
return empty_result if tag_list.empty?
joins = []
conditions = []
context = options.delete(:on)
alias_base_name = undecorated_table_name.gsub('.','_')
if options.delete(:exclude)
tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ?", t]) }.join(" OR ")
conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
elsif options.delete(:any)
# get tags, drop out if nothing returned (we need at least one)
tags = ActsAsTaggableOn::Tag.named_any(tag_list)
return scoped(:conditions => "1 = 0") unless tags.length > 0
# setup taggings alias so we can chain, ex: items_locations_taggings_awesome_cool_123
# avoid ambiguous column name
taggings_context = context ? "_#{context}" : ''
#TODO: fix alias to be smaller
taggings_alias = "#{alias_base_name}#{taggings_context}_taggings_#{tags.map(&:safe_name).join('_')}_#{rand(1024)}"
tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
# don't need to sanitize sql, map all ids and join with OR logic
conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{t.id}" }.join(" OR ")
select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one?
joins << tagging_join
else
tags = ActsAsTaggableOn::Tag.named_any(tag_list)
return empty_result unless tags.length == tag_list.length
tags.each do |tag|
prefix = "#{tag.safe_name}_#{rand(1024)}"
taggings_alias = "#{alias_base_name}_taggings_#{prefix}"
tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" +
" AND #{taggings_alias}.tag_id = #{tag.id}"
tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
joins << tagging_join
end
end
taggings_alias, tags_alias = "#{alias_base_name}_taggings_group", "#{alias_base_name}_tags_group"
if options.delete(:match_all)
joins << "LEFT OUTER JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}"
group = "#{group_columns} HAVING COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
end
scoped(:select => select_clause,
:joins => joins.join(" "),
:group => group,
:conditions => conditions.join(" AND "),
:order => options[:order],
:readonly => false)
end
到rocket_tags
def with_tag_context context
if context
where{taggings.context == my{context} }
else
where{}
end
end
def tagged_with tags_list, options = {}
on = options.delete :on
all = options.delete :all
q = if all
joins{tags}.where{
id.in(
my{self}.
select{id}.
joins{tags}.
where{tags.name.in(my{tags_list})}.
group{~id}.
having{count(~id)==my{tags_list.length}}.
with_tag_context(my{on})
)
}
else
joins{tags}.where{tags.name.in(my{tags_list})}.with_tag_context(on)
end
q.select{"distinct #{my{table_name}}.*"}
end
这是很多清洁剂,虽然我不声称已经处理每一个功能的acts_as_taggable_on已经实施。总是有明天:)
所以,如果你想要一个标签库,你可以潜入并添加功能到rocket_tag可能是你想要的。
它也注意性能,避免加载相关标签时出现N + 1问题。这是值得一看,但是目前我还需要alpha,因为我的项目需要它们。
顺便说一句。感谢作为标签的行为。我不会燃烧图书馆。我借用了架构和想法,但是当我想修复自己的功能时,我觉得代码中的SQL风格很难理解,并且在使用https://github.com/ernie/squeel来满足我的AR查询需求后,我觉得我可以更好地使用干净的平板。
RocketTag还具备全面的RSpec的测试套件https://github.com/bradphelan/rocket_tag/blob/master/spec/rocket_tag/taggable_spec.rb
警告:仅限Ruby 1.9.2 + – 2012-04-16 18:34:58
- 1. 选择标记在rails 3中
- 2. Rails 3标记问题,acts_as_taggable_on
- 3. Rails 3提交标记+ html_safe
- 4. Rails 3中不显示HTML的标记
- 5. 在Rails 3中敲除3
- 6. 在rails 3中的responds_to_parent 3
- 7. 组标记3.
- 8. Bootstrap 3标记
- 9. Rails 3与标记匹配的路由
- 10. Uploadify和rails 3真实性标记
- 11. 的Rails 3 - 帮助用的form_for标记
- 12. Rails 3 - select_tag helper - 空白选项标记
- 13. 在Rails 3中
- 14. 在Rails 3中
- 15. 在Rails 3中
- 16. 在Rails 3中
- 17. 在Rails 3中
- 18. 在Rails 3中
- 19. 在Rails 3中播种数千条记录3
- 20. 在Rails 3中删除一条链接的两条记录3
- 21. 标记的OpenLayers 3
- 22. Rails 3 public_activity,销毁记录
- 23. Rails 3模型记录器
- 24. Rails:每做3条记录
- 25. Assosiations在Rails 3中
- 26. POST在rails 3中
- 27. Rails 3中的Has_and_belongs_to_many 3
- 28. Rails 3中的路线3
- 29. Rails 3中使用distance_of_time_in_words 3
- 30. Rails 3中的词库3
您是否尝试过这样的:https://github.com/mbleigh/acts-as-taggable-on? – Phaenotyp 2011-02-27 01:13:24