레일스 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
내가 어제 만든 새로운 라이브러리입니다. 가능한 한 태그 라이브러리를 구현하는 데 필요한 무서운 SQL이 모두 인 경우 Ernie Miller의 축복형 젬 을 사용하여 구현되었습니다. 은 매우 깨끗합니다. 나는 모든 acts_as_taggable_on가 구현 한 기능을 처리했다고 주장하지 않습니다하지만
는 많은 청소기입니다
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
을 rocket_tags하는 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_tag에 기능을 추가하여 원하는 것을 추가 할 수 있습니다.
또한 성능에주의하고 관련 태그를로드 할 때 N + 1 문제를 방지합니다. 볼만한 가치가 있지만 지금은 알파이며 프로젝트에서 요구하는대로 기능을 추가하겠습니다.
BTW. 태그와 같은 행위에 감사드립니다. 나는 도서관에 불을 붙이는 방법이 아니다. 나는 스키마와 아이디어를 빌려 왔지만 자신 만의 기능을 고치고 자 할 때 코드의 SQL 스타일이 이해하기가 어려웠고을 AR 쿼리에 사용하면 깨끗한 슬레이트로 더 잘 작업 할 수 있다고 생각했습니다. . https://github.com/mbleigh/acts-as-taggable-on :
RocketTag도 https://github.com/bradphelan/rocket_tag/blob/master/spec/rocket_tag/taggable_spec.rb
경고 : Ruby 1.9.2 이상 –
- 1. 레일스 3 메일 링리스트
- 2. 레일스 3. 고유 쿼리
- 3. 레일스 3 : ActionMailer
- 4. 레일스 3 메일러 : 날짜
- 5. 레일스 3 지연 메일
- 6. 레일스 컨텍스트에서 동적 태그 생성
- 7. 사진 태그 지정 C#
- 8. 블로그 단락 태그 지정
- 9. 데이터베이스 태그 지정 구조
- 10. 레일스 3 테이블에 필드 추가하기
- 11. 레일스 3 개의 MySQL 관계
- 12. 레일스 3. 링크에 대한 Google 동향 스크랩
- 13. Java의 태그 지정 인터페이스
- 14. C++ 소스 태그 지정
- 15. nltk로 맞춤 태그 지정
- 16. HOWTO : 프로세스에 태그 지정
- 17. 태그 지정 사전 데이터
- 18. 문자열에 프로세스 태그 지정
- 19. JDO에서 태그 지정 구현하기
- 20. Django에서 GAE로 태그 지정
- 21. 이름 지정 태그 (Wordpress)
- 22. 레일 태그 지정 솔루션
- 23. 태그 지정/인코딩 포인터
- 24. Mercurial 태그 지정/분기 전략
- 25. jQuery를 레일스 이미지 태그/사각형 선택
- 26. 태그 지정 및 태그 테스트 방법이 있습니다.
- 27. 레일 태그 지정 및 태그 목록
- 28. 데이터베이스 개체 (문자열 태그) 태그 지정 및 태그 조회
- 29. Cakephp 태그 지정 - 자동 저장 새 태그 및 태그 관계
- 30. 레일 3 - 기사 태그 제한
는 당신이 봤어 포괄적 인 RSpec에 테스트 스위트를 가지고? – Phaenotyp