minimal_tags 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3118809a99ce6d913ecca4bf1d8d22aaa03346b0
4
+ data.tar.gz: c983175357456a54692f580ebacc48f3fea2297b
5
+ SHA512:
6
+ metadata.gz: 19132c49f3f729cc9fa755e7978cff8962a62e8ca6301c064f3d4540d510cdaa40070e07c86ef1b95b1e130e238a0ca2bfc9d6a271c7ba00d8b0e6203469da12
7
+ data.tar.gz: 091f14403dda0229c6c942af5036786683f34163c72fa9e35238c2ee61fa55182e21a6a5f7590e84c4091e424636a3e34bb61aaa5e680c0e5043b0e0e106ced3
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ test/coverage
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.0
5
+ - 2.2.3
6
+ services:
7
+ - mongodb
8
+ - postgresql
9
+ before_install:
10
+ - gem install bundler -v 1.10.6
11
+ before_script:
12
+ - psql -c 'create database minimal_tags;' -U postgres
13
+ addons:
14
+ code_climate:
15
+ repo_token: 3c954617ba40beceb056cc73b82e00a6dc1fa2193cda386dc6c2128bdd61a804
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ [![Build Status](https://travis-ci.org/harrisbaird/minimal_tags.svg?branch=master)](https://travis-ci.org/harrisbaird/minimal_tags)
2
+ [![Code Climate](https://codeclimate.com/github/harrisbaird/minimal_tags/badges/gpa.svg)](https://codeclimate.com/github/harrisbaird/minimal_tags)
3
+ [![Test Coverage](https://codeclimate.com/github/harrisbaird/minimal_tags/badges/coverage.svg)](https://codeclimate.com/github/harrisbaird/minimal_tags/coverage)
4
+ [![Inline docs](http://inch-ci.org/github/harrisbaird/minimal_tags.svg?branch=master)](http://inch-ci.org/github/harrisbaird/minimal_tags)
5
+
6
+ ---
7
+
8
+ # MinimalTags
9
+
10
+ MinimalTags is a tiny gem for adding tagging support to [Mongoid](https://github.com/mongodb/mongoid) and ActiveRecord (Currently only Postgresql).
11
+
12
+ Multiple tag fields can be used, each with their own way of formatting.
13
+
14
+ ## Installation
15
+
16
+ Add to your Gemfile:
17
+
18
+ ```ruby
19
+ gem 'minimal_tags'
20
+ ```
21
+
22
+ ### Mongoid
23
+ There is nothing else to add, fields will be created when you define your tag fields.
24
+
25
+ ### ActiveRecord
26
+
27
+ Add the following migration for each tag field you want.
28
+
29
+ ```ruby
30
+ class AddTagsToPosts < ActiveRecord::Migration
31
+ def change
32
+ add_column :posts, :tags, :text, default: [], null: false, array: true
33
+ add_index :posts, :tags, using: :gin
34
+ end
35
+ end
36
+
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ Start by including the `MinimalTags` module and define your tag fields
42
+ with the `tag_field` method.
43
+
44
+ ```ruby
45
+ class Document
46
+ include Mongoid::Document
47
+ include MinimalTags
48
+
49
+ tag_field :tags
50
+ tag_field :upcase_tags, formatter: UpcaseFormatter.new
51
+ end
52
+ ```
53
+
54
+ You can define multiple tag fields, just ensure they have unique names.
55
+ Formatters can be defined on each tag field if needed, otherwise the default be used.
56
+
57
+ ## Searching
58
+ The following scopes are also added for each tag field and can be chained:
59
+ `.any_*`, `.all_*`
60
+
61
+ ```ruby
62
+ Document.any_tags(['a', 'b', 'c'])
63
+ Document.all_tags(['a', 'b', 'c'])
64
+ ```
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Write your tests
71
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
72
+ 5. Push to the branch (`git push origin my-new-feature`)
73
+ 6. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ require 'yard'
5
+ YARD::Rake::YardocTask.new(:doc)
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << 'test'
9
+ t.libs << 'lib'
10
+ t.test_files = FileList['test/**/test_*.rb']
11
+ end
12
+
13
+ task default: :test
@@ -0,0 +1,24 @@
1
+ require 'minimal_tags/simple_formatter'
2
+ require 'minimal_tags/version'
3
+
4
+ module MinimalTags
5
+ class << self
6
+ attr_writer :default_formatter
7
+
8
+ def included(base)
9
+ ancestors = base.ancestors.collect(&:to_s)
10
+
11
+ if ancestors.include?('Mongoid::Document')
12
+ require 'minimal_tags/persistence/mongoid'
13
+ base.send :extend, Persistence::Mongoid
14
+ elsif ancestors.include?('ActiveRecord::Base')
15
+ require 'minimal_tags/persistence/activerecord'
16
+ base.send :extend, Persistence::Activerecord
17
+ end
18
+ end
19
+
20
+ def default_formatter
21
+ @default_formatter ||= SimpleFormatter.new
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ module MinimalTags
2
+ module Persistence
3
+ module Activerecord
4
+ TAG_SEARCH_TYPES = {
5
+ all: '@>',
6
+ any: '&&'
7
+ }
8
+
9
+ ##
10
+ # Creates a tag field, index, search methods and a callback for tag
11
+ # normalization on save.
12
+ #
13
+ # @example
14
+ # class Posts < ActiveRecord::Base
15
+ # include MinimalTags
16
+ #
17
+ # tag_field :tags
18
+ # end
19
+ #
20
+ # doc = Posts.create(tags: ['hello world', 'this is a test']).tags
21
+ # # => ['hello-world', 'this-is-a-test']
22
+ #
23
+ # doc == Posts.any_tags(['HELLO WORLD']).first
24
+ # # => true
25
+ #
26
+ # @param [String] field_name The field name to use in mongo and searching methods
27
+ # @param [Object] formatter The formatter to use, overriding the default
28
+ def tag_field(field_name, formatter: MinimalTags.default_formatter)
29
+ # Create the scopes for searching tags
30
+ TAG_SEARCH_TYPES.each do |prefix, operator|
31
+ scope "#{prefix}_#{field_name}", lambda { |tags|
32
+ where("#{field_name} #{operator} ARRAY[?]::varchar[]", formatter.normalize(tags))
33
+ }
34
+ end
35
+
36
+ # Normalize tags on save
37
+ set_callback(:save, :before) do
38
+ tags = read_attribute(field_name)
39
+ write_attribute(field_name, formatter.normalize(tags))
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
1
+ module MinimalTags
2
+ module Persistence
3
+ module Mongoid
4
+ TAG_SEARCH_TYPES = {
5
+ all: 'all',
6
+ any: 'in'
7
+ }
8
+
9
+ ##
10
+ # Creates a tag field, index, search methods and a callback for tag
11
+ # normalization on save.
12
+ #
13
+ # @example
14
+ # class Posts
15
+ # include Mongoid::Document
16
+ # include MinimalTags
17
+ #
18
+ # tag_field :tags
19
+ # end
20
+ #
21
+ # doc = Posts.create(tags: ['hello world', 'this is a test']).tags
22
+ # # => ['hello-world', 'this-is-a-test']
23
+ #
24
+ # doc == Posts.any_tags(['HELLO WORLD']).first
25
+ # # => true
26
+ #
27
+ # @param [String] field_name The field name to use in mongo and searching methods
28
+ # @param [Object] formatter The formatter to use, overriding the default
29
+ def tag_field(field_name, formatter: MinimalTags.default_formatter)
30
+ field field_name, type: Array, default: []
31
+ index field_name => 1
32
+
33
+ # Create the scopes for searching tags
34
+ TAG_SEARCH_TYPES.each do |prefix, type|
35
+ scope "#{prefix}_#{field_name}", lambda { |tags|
36
+ criteria.send(type, field_name => formatter.normalize(tags))
37
+ }
38
+ end
39
+
40
+ # Normalize tags on save
41
+ set_callback(:save, :before) do
42
+ tags = read_attribute(field_name)
43
+ write_attribute(field_name, formatter.normalize(tags))
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ module MinimalTags
2
+ # A very simple tag formatter using ActiveSupport's parameterize.
3
+ # You should create your own rather than using this.
4
+ class SimpleFormatter
5
+ ##
6
+ # Returns an array of normalized tags
7
+ #
8
+ # @param [Array] tags Tags to normalize
9
+ #
10
+ # @return [Array] Unique, parameterized tags
11
+ def normalize(tags)
12
+ tags.map(&:parameterize).uniq
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module MinimalTags
2
+ VERSION = '0.2.0'
3
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'minimal_tags/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'minimal_tags'
8
+ spec.version = MinimalTags::VERSION
9
+ spec.authors = ['harrisbaird']
10
+ spec.email = ['mydancake@gmail.com']
11
+
12
+ spec.summary = 'Simple tag fields for ActiveRecord and Mongoid.'
13
+ spec.description = 'Simple tag fields for ActiveRecord and Mongoid.'
14
+ spec.homepage = 'https://github.com/harrisbaird/minimal_tags'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = 'exe'
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'mongoid', '>= 4.0.0', '<= 6.0.0'
22
+ spec.add_development_dependency 'activerecord', '>= 4.0.0', '<= 6.0.0'
23
+ spec.add_development_dependency 'pg'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.10'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'yard'
28
+ spec.add_development_dependency 'minitest'
29
+ spec.add_development_dependency 'codeclimate-test-reporter'
30
+ end
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minimal_tags
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - harrisbaird
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-12-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mongoid
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ - - "<="
21
+ - !ruby/object:Gem::Version
22
+ version: 6.0.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 4.0.0
30
+ - - "<="
31
+ - !ruby/object:Gem::Version
32
+ version: 6.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: activerecord
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 4.0.0
40
+ - - "<="
41
+ - !ruby/object:Gem::Version
42
+ version: 6.0.0
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 4.0.0
50
+ - - "<="
51
+ - !ruby/object:Gem::Version
52
+ version: 6.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: pg
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: bundler
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '1.10'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '1.10'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rake
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '10.0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '10.0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: yard
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: minitest
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ - !ruby/object:Gem::Dependency
124
+ name: codeclimate-test-reporter
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ description: Simple tag fields for ActiveRecord and Mongoid.
138
+ email:
139
+ - mydancake@gmail.com
140
+ executables: []
141
+ extensions: []
142
+ extra_rdoc_files: []
143
+ files:
144
+ - ".gitignore"
145
+ - ".travis.yml"
146
+ - Gemfile
147
+ - README.md
148
+ - Rakefile
149
+ - lib/minimal_tags.rb
150
+ - lib/minimal_tags/persistence/activerecord.rb
151
+ - lib/minimal_tags/persistence/mongoid.rb
152
+ - lib/minimal_tags/simple_formatter.rb
153
+ - lib/minimal_tags/version.rb
154
+ - minimal_tags.gemspec
155
+ homepage: https://github.com/harrisbaird/minimal_tags
156
+ licenses: []
157
+ metadata: {}
158
+ post_install_message:
159
+ rdoc_options: []
160
+ require_paths:
161
+ - lib
162
+ required_ruby_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ required_rubygems_version: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ requirements: []
173
+ rubyforge_project:
174
+ rubygems_version: 2.5.0
175
+ signing_key:
176
+ specification_version: 4
177
+ summary: Simple tag fields for ActiveRecord and Mongoid.
178
+ test_files: []
179
+ has_rdoc: