polytag 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.DS_Store +0 -0
  2. data/.pryrc +27 -0
  3. data/.rspec +3 -1
  4. data/README.md +26 -4
  5. data/lib/.DS_Store +0 -0
  6. data/lib/generators/polytag/.DS_Store +0 -0
  7. data/lib/generators/polytag/install/.DS_Store +0 -0
  8. data/lib/generators/polytag/install/templates/create_polytag_tables.rb +25 -11
  9. data/lib/polytag.rb +221 -58
  10. data/lib/polytag/concerns/tag_owner.rb +31 -0
  11. data/lib/polytag/concerns/tag_owner/association_extensions.rb +15 -0
  12. data/lib/polytag/concerns/tag_owner/association_extensions/owned_tags.rb +16 -0
  13. data/lib/polytag/concerns/tag_owner/class_helpers.rb +25 -0
  14. data/lib/polytag/concerns/tag_owner/model_helpers.rb +78 -0
  15. data/lib/polytag/concerns/taggable.rb +24 -0
  16. data/lib/polytag/concerns/taggable/association_extensions.rb +15 -0
  17. data/lib/polytag/concerns/taggable/class_helpers.rb +16 -0
  18. data/lib/polytag/concerns/taggable/model_helpers.rb +60 -0
  19. data/lib/polytag/connection.rb +27 -0
  20. data/lib/polytag/exceptions.rb +7 -0
  21. data/lib/polytag/tag.rb +6 -24
  22. data/lib/polytag/tag_group.rb +8 -46
  23. data/lib/polytag/version.rb +1 -1
  24. data/polytag.gemspec +7 -3
  25. data/spec/spec_helper.rb +15 -10
  26. data/spec/specs/owner_spec.rb +104 -0
  27. data/spec/specs/taggable_with_owner_spec.rb +120 -0
  28. data/spec/specs/taggable_without_owner_spec.rb +59 -0
  29. data/spec/support/active_record.rb +6 -6
  30. data/spec/support/owner.rb +1 -1
  31. data/spec/support/taggable.rb +3 -0
  32. metadata +115 -46
  33. checksums.yaml +0 -7
  34. data/circle.yml +0 -3
  35. data/lib/polytag/tag_group/owner.rb +0 -17
  36. data/lib/polytag/tag_relation.rb +0 -15
  37. data/spec/specs/polytag_querying_spec.rb +0 -56
  38. data/spec/specs/polytag_test_taggable_four_spec.rb +0 -54
  39. data/spec/specs/polytag_test_taggable_one_spec.rb +0 -47
  40. data/spec/specs/polytag_test_taggable_three_spec.rb +0 -51
  41. data/spec/specs/polytag_test_taggable_two_spec.rb +0 -51
  42. data/spec/support/test_taggable_four.rb +0 -7
  43. data/spec/support/test_taggable_one.rb +0 -3
  44. data/spec/support/test_taggable_three.rb +0 -8
  45. data/spec/support/test_taggable_two.rb +0 -7
@@ -0,0 +1,31 @@
1
+ module Polytag
2
+ module Concerns
3
+ module TagOwner
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ include ClassHelpers
8
+ end
9
+
10
+ included do
11
+ has_many :tag_groups,
12
+ class_name: '::Polytag::TagGroup',
13
+ dependent: :destroy,
14
+ as: :owner do
15
+ include AssociationExtensions
16
+ end
17
+
18
+ has_many :owned_tags,
19
+ class_name: '::Polytag::Connection',
20
+ dependent: :destroy,
21
+ as: :owner do
22
+ include AssociationExtensions::OwnedTags
23
+ end
24
+ end
25
+
26
+ def tag_group
27
+ ModelHelpers.new(self)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ module Polytag
2
+ module Concerns
3
+ module TagOwner
4
+ module AssociationExtensions
5
+ def default
6
+ where(name: :default).first
7
+ end
8
+
9
+ def get(group)
10
+ where(name: "#{group}".strip).first
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Polytag
2
+ module Concerns
3
+ module TagOwner
4
+ module AssociationExtensions
5
+ module OwnedTags
6
+ def get(tag, args = {})
7
+ tag_group_query = ::Polytag.get(:tag_group, nil, args.merge(owner: proxy_association.owner))
8
+ query = ::Polytag.get(:tag, nil, tag).where(polytag_tag_group_id: tag_group_query.select(:id))
9
+ where(polytag_connections: {polytag_tag_group_id: query.select(:id)})
10
+ end
11
+ alias find get
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module Polytag
2
+ module Concerns
3
+ module TagOwner
4
+ module ClassHelpers
5
+ def has_tag_group(group)
6
+ query = ::Polytag.get foc: nil,
7
+ tag_group: group
8
+
9
+ includes(:tag_groups).where(polytag_tag_groups: {id: query.select(:id)})
10
+ end
11
+
12
+ def has_tag(tag, group = nil)
13
+ if group
14
+ tag_group_query = ::Polytag.get(:tag_group, nil, group).select(:id)
15
+ query = ::Polytag.get(:tag, nil, tag).where(polytag_tag_group_id: tag_group_query)
16
+ else
17
+ query = ::Polytag.get(:tag, nil, tag)
18
+ end
19
+
20
+ includes(:tag_groups).where(polytag_tag_groups: {id: query.select(:id)})
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,78 @@
1
+ module Polytag
2
+ module Concerns
3
+ module TagOwner
4
+ class ModelHelpers
5
+ def initialize(owner)
6
+ @owner = owner
7
+ end
8
+
9
+ def new(group)
10
+ ::Polytag.get tag_group: group,
11
+ foc: :first_or_create,
12
+ owner: @owner
13
+ end
14
+ alias add new
15
+ alias create new
16
+
17
+ def del(group)
18
+ return false unless exist?(group)
19
+ group = ::Polytag.get tag_group: group,
20
+ owner: @owner,
21
+ foc: :first
22
+
23
+ group.destroy
24
+ true
25
+ end
26
+ alias delete del
27
+ alias remove del
28
+ alias destroy del
29
+
30
+ def exist?(group)
31
+ group = ::Polytag.get tag_group: group,
32
+ owner: @owner,
33
+ foc: :first
34
+
35
+ # Return the result
36
+ group.is_a?(::Polytag::TagGroup)
37
+ rescue ActiveRecord::RecordNotFound
38
+ false
39
+ end
40
+
41
+ def new_tag(tag, group = nil)
42
+ ::Polytag.get tag_group: group,
43
+ foc: :first_or_create,
44
+ owner: @owner,
45
+ tag: tag
46
+ end
47
+ alias add_tag new_tag
48
+ alias create_tag new_tag
49
+
50
+ def del_tag(tag, group = nil)
51
+ return false unless owns_tag?(group, tag)
52
+ tag = ::Polytag.get tag_group: group,
53
+ owner: @owner,
54
+ foc: :first,
55
+ tag: tag
56
+
57
+ tag.destroy
58
+ true
59
+ end
60
+ alias delete_tag del_tag
61
+ alias remove_tag del_tag
62
+ alias destroy_tag del_tag
63
+
64
+ def owns_tag?(tag, group = nil)
65
+ tag = ::Polytag.get tag_group: group,
66
+ owner: @owner,
67
+ foc: :first,
68
+ tag: tag
69
+
70
+ # Return the result
71
+ tag.is_a?(::Polytag::Tag)
72
+ rescue ActiveRecord::RecordNotFound
73
+ false
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,24 @@
1
+ module Polytag
2
+ module Concerns
3
+ module Taggable
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ include ClassHelpers
8
+ end
9
+
10
+ included do
11
+ has_many :tags,
12
+ class_name: '::Polytag::Connection',
13
+ dependent: :destroy,
14
+ as: :tagged do
15
+ include AssociationExtensions
16
+ end
17
+ end
18
+
19
+ def tag
20
+ ModelHelpers.new(self)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ module Polytag
2
+ module Concerns
3
+ module Taggable
4
+ module AssociationExtensions
5
+ def tag_group(args = {})
6
+ includes(:tag_group).merge(::Polytag.get(tag_group: args[:tag_group], owner: args[:tag_group_owner]))
7
+ end
8
+
9
+ def no_tag_group
10
+ where(polytag_tag_group_id: nil, owner_type: nil, owner_id: nil)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Polytag
2
+ module Concerns
3
+ module Taggable
4
+ module ClassHelpers
5
+ def has_tag(tag, args = {})
6
+ query = ::Polytag.get tag: tag,
7
+ tag_group: args[:tag_group],
8
+ owner: args[:tag_group_owner],
9
+ foc: nil
10
+
11
+ includes(:tags).where(polytag_connections: {polytag_tag_id: query.select(:id)})
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ module Polytag
2
+ module Concerns
3
+ module Taggable
4
+ class ModelHelpers
5
+ def initialize(owner)
6
+ @owner = owner
7
+ end
8
+
9
+ def new(tag, args = {})
10
+ ::Polytag.get tag: tag,
11
+ foc: :first_or_create,
12
+ tag_group: args[:tag_group],
13
+ owner: args[:tag_group_owner],
14
+ tagged: @owner
15
+ end
16
+ alias add new
17
+ alias create new
18
+
19
+ def del(tag, args = {})
20
+ return false unless exist?(tag, args)
21
+ tag = ::Polytag.get tag: tag,
22
+ tag_group: args[:tag_group],
23
+ owner: args[:tag_group_owner],
24
+ tagged: @owner,
25
+ foc: :first
26
+
27
+ tag.destroy
28
+ true
29
+ end
30
+ alias delete del
31
+ alias remove del
32
+ alias destroy del
33
+
34
+ def get(tag, args = {})
35
+ return false unless exist?(tag, args)
36
+ ::Polytag.get tag: tag,
37
+ tag_group: args[:tag_group],
38
+ owner: args[:tag_group_owner],
39
+ tagged: @owner,
40
+ foc: :first
41
+ end
42
+ alias find get
43
+
44
+ def exist?(tag, args = {})
45
+ tag = ::Polytag.get tag: tag,
46
+ tag_group: args[:tag_group],
47
+ owner: args[:tag_group_owner],
48
+ tagged: @owner,
49
+ foc: :first
50
+
51
+ # Return the result
52
+ tag.is_a?(::Polytag::Connection)
53
+ rescue ActiveRecord::RecordNotFound
54
+ false
55
+ end
56
+ alias has_tag? exist?
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,27 @@
1
+ class Polytag::Connection < ActiveRecord::Base
2
+ self.table_name = :polytag_connections
3
+
4
+ belongs_to :tag,
5
+ class_name: '::Polytag::Tag',
6
+ foreign_key: :polytag_tag_id
7
+
8
+ belongs_to :tag_group,
9
+ class_name: '::Polytag::TagGroup',
10
+ foreign_key: :polytag_tag_group_id
11
+
12
+ belongs_to :owner,
13
+ polymorphic: true
14
+
15
+ belongs_to :tagged,
16
+ polymorphic: true
17
+
18
+ delegate :name,
19
+ to: :tag
20
+
21
+ # Destroy the tag if it is no longer in use
22
+ after_destroy do
23
+ if ! tag.tag_group && tag.tag_connections.count < 1
24
+ tag.destroy
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ module Polytag
2
+ class CantFindPolytagModel < ActiveRecord::RecordNotFound; end
3
+ class NotTagOwnerOrTaggable < Exception; end
4
+ class NotPolytagModel < Exception; end
5
+ class NotTagOwner < Exception; end
6
+ class NotTaggable < Exception; end
7
+ end
@@ -1,29 +1,11 @@
1
1
  class Polytag::Tag < ActiveRecord::Base
2
2
  self.table_name = :polytag_tags
3
- belongs_to :polytag_tag_group, class_name: '::Polytag::TagGroup'
4
- belongs_to :tag_group, class_name: '::Polytag::TagGroup',
5
- foreign_key: :polytag_tag_group_id
6
3
 
7
- has_many :polytag_tag_relations, class_name: '::Polytag::TagRelation',
8
- foreign_key: :polytag_tag_id,
9
- dependent: :destroy
4
+ has_many :tag_connections,
5
+ class_name: '::Polytag::Connection',
6
+ foreign_key: :polytag_tag_id
10
7
 
11
- has_many :relations, class_name: '::Polytag::TagRelation',
12
- foreign_key: :polytag_tag_id,
13
- dependent: :destroy
14
-
15
- # Indiscrimanetly get
16
- # the tagged models
17
- def tagged
18
- polytag_tag_relations.tagged.flatten
19
- end
20
-
21
- # Cleanup group if there are
22
- # no more tags left on the group
23
- after_destroy do
24
- polytag_tag_group.reload
25
- if polytag_tag_group.tags.count < 0
26
- polytag_tag_group.destroy
27
- end
28
- end
8
+ belongs_to :tag_group,
9
+ class_name: '::Polytag::TagGroup',
10
+ foreign_key: :polytag_tag_group_id
29
11
  end
@@ -1,52 +1,14 @@
1
1
  class Polytag::TagGroup < ActiveRecord::Base
2
2
  self.table_name = :polytag_tag_groups
3
3
 
4
- has_many :polytag_tag, class_name: '::Polytag::Tag',
5
- foreign_key: :polytag_tag_group_id,
6
- dependent: :destroy
4
+ has_many :tag_connections,
5
+ class_name: '::Polytag::Connection',
6
+ foreign_key: :polytag_tag_group_id
7
7
 
8
- has_many :tag, class_name: '::Polytag::Tag',
9
- foreign_key: :polytag_tag_group_id,
10
- dependent: :destroy
8
+ has_many :tags,
9
+ class_name: '::Polytag::Tag',
10
+ foreign_key: :polytag_tag_group_id
11
11
 
12
- belongs_to :owner, polymorphic: true
13
-
14
- # Cleanup tag if there are
15
- # no more relations left on the tag
16
- after_destroy do
17
- tag.reload
18
- if tag.relations.count < 0
19
- tag.destroy
20
- end
21
- end
22
-
23
- class << self
24
- def search_by_hash(hash = {})
25
- return self if hash.empty?
26
- conditions = {}
27
-
28
- # Query by owner information
29
- if hash[:owner]
30
- conditions.merge!(owner_type: "#{hash[:owner].class}")
31
- conditions.merge!(owner_id: hash[:owner].id)
32
- else
33
- if hash[:owner_type]
34
- conditions.merge!(owner_type: "#{hash[:owner_type]}")
35
- conditions.merge!(owner_id: hash[:owner_id]) if hash[:owner_id]
36
- end
37
- end
38
-
39
- # Query by tag group name
40
- conditions.merge!(name: "#{hash[:name]}") if hash[:name]
41
-
42
- # Query by tag group id
43
- conditions.merge!(id: hash[:id]) if hash[:id]
44
-
45
- where(conditions)
46
- end
47
-
48
- def find_by_hash(hash = {})
49
- search_by_hash(hash).first
50
- end
51
- end
12
+ belongs_to :owner,
13
+ polymorphic: true
52
14
  end
@@ -1,3 +1,3 @@
1
1
  module Polytag
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -19,11 +19,15 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "awesome_print"
23
+ spec.add_development_dependency "database_cleaner"
23
24
  spec.add_development_dependency "rspec"
24
25
  spec.add_development_dependency "rspec-rails"
26
+ spec.add_development_dependency "fuubar"
25
27
  spec.add_development_dependency "sqlite3"
26
- spec.add_development_dependency "awesome_print"
27
- spec.add_dependency "activerecord", ">= 3.2.13"
28
+ spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "pry"
30
+
28
31
  spec.add_dependency "activesupport", ">= 3.2.13"
32
+ spec.add_dependency "activerecord", ">= 3.2.13"
29
33
  end