Guest User

Untitled

a guest
Oct 19th, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.55 KB | None | 0 0
  1. # An unfinished sketch of a module to add 'taggable' behaviour to
  2. # an item in the gov.uk publishing domain model. It won't work as is
  3. # but is intended to demonstrate one mechanism for representing
  4. # tagging.
  5. #
  6. # This could work and is quite a rails-y way to do it, but it feels
  7. # like it's perhaps doing too much work to tie together the domain
  8. # model and its persistence and so it'd be worth exploring alternatives.
  9. #
  10. module Taggable
  11. module ClassMethods
  12. def stores_tags_for(*keys)
  13. keys.map!(&:to_s)
  14.  
  15. keys.each { |k|
  16. attr_accessor k
  17.  
  18. # define_method "#{k.singularize}=" do |values|
  19. # # tag_ids.clear
  20. # # tags.clear
  21.  
  22. # values.each do |value|
  23. # tag_id, tag = Tag.id_and_entity(value)
  24.  
  25. # tag_ids.push(tag_id) unless tag_ids.include?(tag_id)
  26. # tags.push(tag_id) unless tags.include?(tag)
  27. # end
  28. # end
  29.  
  30. # define_method "#{k.singularize}_ids" do
  31. # tags.select { |t| t.tag_type == k.singularize }.collect(&:tag_id)
  32. # end
  33.  
  34. # define_method k do
  35. # tags.select { |t| t.tag_type == k.singularize }
  36. # end
  37. }
  38. self.tag_keys = keys
  39. end
  40.  
  41. def has_primary_tag_for(key)
  42. raise "Only one primary tag type allowed" unless key.is_a?(Symbol)
  43.  
  44. method_name = "primary_#{key.to_s.singularize}"
  45. attr_accessor method_name
  46. # define_method "#{method_name}=" do |value|
  47. # tag_id, tag = Tag.id_and_entity(value)
  48.  
  49. # tag_ids.delete(tag_id)
  50. # tag_ids.unshift(tag_id)
  51.  
  52. # tags.delete(tag)
  53. # tags.unshift(tag)
  54. # end
  55.  
  56. # define_method method_name do
  57. # __send__(key.to_s.pluralize).first
  58. # end
  59. end
  60. end
  61.  
  62. def self.included(klass)
  63. klass.extend ClassMethods
  64. klass.field :tag_ids, type: Array, default: []
  65. klass.attr_protected :tags, :tag_ids
  66. klass.cattr_accessor :tag_keys, :primary_tag_keys
  67. klass.private :tags, :tag_ids
  68. end
  69.  
  70. def reconcile_tags
  71. general_tags = []
  72. special_tags = []
  73.  
  74. self.class.tag_keys.each do |key|
  75. general_tags += __send__(key).to_a
  76. end
  77.  
  78. self.class.primary_tag_keys.each do |key|
  79. special_tags << __send__("primary_#{key.to_s.singularize}")
  80. end
  81.  
  82. # Don't duplicate tags
  83. general_tags -= special_tags
  84.  
  85. # Fill up tag_ids
  86. self.tag_ids = (special_tags + general_tags).reject { |t| t.blank? }
  87. end
  88.  
  89. # TODO: Work out best way to memoise this
  90. def tags
  91. TagRepository.load_all_with_ids(tag_ids).to_a
  92. end
  93.  
  94. def save
  95. reconcile_tags
  96. parent
  97. end
  98. end
Add Comment
Please, Sign In to add comment