tagutils 0.1.0 → 0.1.1

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.
File without changes
@@ -3,6 +3,10 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/tagutils.rb
6
- lib/tagutils/models.rb
6
+ lib/tagutils/active_record.rb
7
+ lib/tagutils/models/tag.rb
8
+ lib/tagutils/models/tagging.rb
7
9
  lib/tagutils/schema.rb
8
10
  lib/tagutils/version.rb
11
+ test/helper.rb
12
+ test/test_models.rb
data/README.md CHANGED
@@ -7,9 +7,23 @@ tagutils gems - tag utilities (tag, taggings, tag list, etc.)
7
7
  * gem :: [rubygems.org/gems/tagutils](https://rubygems.org/gems/tagutils)
8
8
  * rdoc :: [rubydoc.info/gems/tagutils](http://rubydoc.info/gems/tagutils)
9
9
 
10
+
10
11
  ## Usage
11
12
 
12
- TBD
13
+ ~~~
14
+ class Country < ActiveRecord::Base
15
+ has_many :taggings, class_name: 'TagDb::Model::Tagging', :as => :taggable
16
+ has_many :tags, class_name: 'TagDb::Model::Tag', :through => :taggings
17
+ end
18
+ ~~~
19
+
20
+ or
21
+
22
+ ~~~
23
+ class Country < ActiveRecord::Base
24
+ has_many_tags
25
+ end
26
+ ~~~
13
27
 
14
28
 
15
29
  ## Real World Usage
@@ -21,6 +35,27 @@ TBD
21
35
 
22
36
  ## Alternatives
23
37
 
38
+
39
+ ### Tags
40
+
41
+ - [gutentag](https://github.com/pat/gutentag)
42
+
43
+ ~~~
44
+ create_table :taggings do |t|
45
+ t.integer :tag_id, null: false
46
+ t.integer :taggable_id, null: false
47
+ t.string :taggable_type, null: false
48
+ t.timestamps
49
+ end
50
+
51
+ create_table :tags do |t|
52
+ t.string :name, null: false
53
+ t.integer :taggings_count, null: false, default: 0
54
+ t.timestamps
55
+ end
56
+ ~~~
57
+
58
+
24
59
  - [acts_as_taggable_on](https://github.com/mbleigh/acts-as-taggable-on)
25
60
 
26
61
  ~~~
@@ -30,9 +65,9 @@ end
30
65
 
31
66
  create_table :taggings do |t|
32
67
  t.references :tag
33
- t.references :taggable, :polymorphic => true
34
- t.references :tagger, :polymorphic => true
35
- t.string :context, :limit => 128
68
+ t.references :taggable, polymorphic: true
69
+ t.references :tagger, polymorphic: true
70
+ t.string :context, limit: 128
36
71
  t.datetime :created_at
37
72
  end
38
73
  ~~~
@@ -44,14 +79,14 @@ end
44
79
 
45
80
  ~~~
46
81
  create_table :tags do |t|
47
- t.string :name, :default => ''
48
- t.string :kind, :default => ''
82
+ t.string :name, default: ''
83
+ t.string :kind, default: ''
49
84
  end
50
85
 
51
86
  create_table :taggings do |t|
52
87
  t.integer :tag_id
53
88
 
54
- t.string :taggable_type, :default => ''
89
+ t.string :taggable_type, default: ''
55
90
  t.integer :taggable_id
56
91
  end
57
92
  ~~~
@@ -67,8 +102,8 @@ end
67
102
 
68
103
  create_table :taggings do |t|
69
104
  t.references :tag
70
- t.references :taggable, :polymorphic => true
71
- t.references :tagger, :polymorphic => true
105
+ t.references :taggable, polymorphic: true
106
+ t.references :tagger, polymorphic: true
72
107
  t.string :context
73
108
  t.datetime :created_at
74
109
  end
@@ -86,15 +121,15 @@ end
86
121
 
87
122
  ~~~
88
123
  create_table :tags do |t|
89
- t.column :name, :string
90
- t.column :taggings_count, :integer, :default => 0, :null => false
124
+ t.string :name
125
+ t.integer :taggings_count, null: false, default: 0
91
126
  end
92
127
 
93
128
  create_table :taggings do |t|
94
- t.column :tag_id, :integer
95
- t.column :taggable_id, :integer
96
- t.column :taggable_type, :string
97
- t.column :user_id, :integer
129
+ t.integer :tag_id
130
+ t.integer :taggable_id
131
+ t.string :taggable_type
132
+ t.integer :user_id
98
133
  end
99
134
  ~~~
100
135
 
@@ -105,15 +140,15 @@ end
105
140
 
106
141
  ~~~
107
142
  create_table :tags do |t|
108
- t.column :name, :string
143
+ t.string :name
109
144
  end
110
-
145
+
111
146
  create_table :taggings do |t|
112
- t.column :tag_id, :integer
113
- t.column :taggable_id, :integer
114
- t.column :taggable_type, :string
115
-
116
- t.column :created_at, :datetime
147
+ t.integer :tag_id
148
+ t.integer :taggable_id
149
+ t.string :taggable_type
150
+
151
+ t.datetime :created_at
117
152
  end
118
153
  ~~~
119
154
 
@@ -123,6 +158,36 @@ end
123
158
  - [Ruby Toolbook - Rails Tagging Category](https://www.ruby-toolbox.com/categories/rails_tagging)
124
159
 
125
160
 
161
+ ### Categories
162
+
163
+ - [categoryz3](https://github.com/tscolari/categoryz3)
164
+
165
+ ~~~
166
+ create_table :categoryz3_categories do |t|
167
+ t.string :name
168
+ t.references :parent
169
+ t.integer :items_count, default: 0
170
+ t.integer :child_items_count, default: 0
171
+ t.integer :childrens_count, default: 0
172
+ t.timestamps
173
+ end
174
+
175
+ create_table :categoryz3_items do |t|
176
+ t.references :category, null: false
177
+ t.references :categorizable, null: false, polymorphic: true
178
+ t.timestamps
179
+ end
180
+
181
+ create_table :categoryz3_child_items do |t|
182
+ t.references :category, null: false
183
+ t.references :categorizable, null: false, polymorphic: true
184
+ t.references :master_item, null: false
185
+ t.timestamps
186
+ end
187
+ ~~~
188
+
189
+ - [acts_as_category](https://github.com/wuwx/acts_as_category)
190
+
126
191
 
127
192
  ## License
128
193
 
data/Rakefile CHANGED
@@ -11,14 +11,15 @@ Hoe.spec 'tagutils' do
11
11
  self.urls = ['https://github.com/rubylibs/tagutils']
12
12
 
13
13
  self.author = 'Gerald Bauer'
14
- self.email = 'webslideshow@googlegroups.com'
14
+ self.email = 'openmundi@googlegroups.com'
15
15
 
16
16
  # switch extension to .markdown for gihub formatting
17
17
  self.readme_file = 'README.md'
18
18
  self.history_file = 'HISTORY.md'
19
19
 
20
20
  self.extra_deps = [
21
- ['logutils', '>= 0.5']
21
+ ['activerecord' ],
22
+ ['logutils', '>= 0.6']
22
23
  ]
23
24
 
24
25
  self.licenses = ['Public Domain']
@@ -28,4 +29,4 @@ Hoe.spec 'tagutils' do
28
29
  }
29
30
 
30
31
 
31
- end
32
+ end
@@ -10,7 +10,11 @@ require 'logutils'
10
10
  require 'tagutils/version' # let it always go first
11
11
 
12
12
  require 'tagutils/schema'
13
- require 'tagutils/models'
13
+ require 'tagutils/models/tag'
14
+ require 'tagutils/models/tagging'
15
+
16
+
17
+ require 'tagutils/active_record' # -- adds has_many_tags macro
14
18
 
15
19
 
16
20
  module TagUtils
@@ -28,6 +32,12 @@ end # module TagUtils
28
32
 
29
33
 
30
34
  module TagDb
35
+
36
+ #####
37
+ # add convenience module alias in plural
38
+ # e.g. lets you use include TagDb::Models
39
+ Models = Model
40
+
31
41
  def self.create
32
42
  CreateDb.new.up
33
43
  ## WorldDb::Model::Prop.create!( key: 'db.schema.world.version', value: VERSION )
@@ -35,14 +45,12 @@ module TagDb
35
45
 
36
46
  # delete ALL records (use with care!)
37
47
  def self.delete!
38
- ## fix: use Deleter (see sportdb etc.)
39
48
  puts '*** deleting tag/tagging table records/data...'
40
49
  Model::Tagging.delete_all
41
50
  Model::Tag.delete_all
42
- end # method delete!
51
+ end
43
52
 
44
53
  def self.tables
45
- ## fix: use Stats class (see sportdb etc.)
46
54
  puts "#{Model::Tag.count} tags"
47
55
  puts "#{Model::Tagging.count} taggings"
48
56
  end
@@ -52,4 +60,3 @@ end # module TagDb
52
60
 
53
61
 
54
62
  puts TagUtils.banner # say hello
55
-
@@ -0,0 +1,40 @@
1
+
2
+
3
+ module ActiveRecord
4
+ class Base
5
+
6
+ def self.has_many_tags( opts={} )
7
+ puts " [TagUtils.has_many_tags] adding taggings n tags has_many assocs to model >#{name}<"
8
+ has_many :taggings, class_name: 'TagDb::Model::Tagging', :as => :taggable
9
+ has_many :tags, class_name: 'TagDb::Model::Tag', :through => :taggings
10
+ end
11
+
12
+ end # class Base
13
+ end # module ActiveRecord
14
+
15
+
16
+
17
+ ####################################################
18
+ # todo/check: use concern - why? why not? e.g
19
+ #
20
+
21
+ =begin
22
+ require 'active_support/concern'
23
+
24
+ module TagUtils::ActiveRecord
25
+ extend ActiveSupport::Concern
26
+
27
+ module ClassMethods
28
+ def has_many_tags
29
+ has_many :taggings, class_name: 'TagDb::Model::Tagging', :as => :taggable
30
+ has_many :tags, class_name: 'TagDb::Model::Tag', :through => :taggings
31
+ end
32
+ end
33
+ end
34
+
35
+ class ActiveRecord::Base
36
+ include TagUtils::ActiveRecord
37
+ end
38
+
39
+ =end
40
+
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ module TagDb
4
+ module Model
5
+
6
+ class Tag < ActiveRecord::Base
7
+
8
+ has_many :taggings
9
+
10
+ ## nb: only allow spaces and underscore inbetween;
11
+ ## do NOT allow digit as first char for now
12
+ validates :key, :format => { :with => /^([a-z]|[a-z][a-z0-9_ ]*[a-z0-9])$/,
13
+ :message => 'expected one or more lowercase letters a-z or 0-9 digits or space or underscore' }
14
+
15
+ scope :by_key, order( 'key desc' )
16
+ scope :by_name, order( 'name desc' )
17
+ scope :top, where( 'grade=1' )
18
+
19
+
20
+ before_save :on_before_save
21
+
22
+ def on_before_save
23
+ # replace space with dash e.g. north america becomes north-america and so on
24
+ self.slug = key.gsub( ' ', '-' )
25
+
26
+ ## if name is empty auto fill w/ key
27
+ self.name = key if name.blank?
28
+ end
29
+
30
+
31
+ ############################################################################
32
+ # alias for name (remove! add depreciated api call) ?? why? why not??
33
+
34
+ def title() name; end
35
+ def title=(value) self.name = value; end
36
+
37
+ scope :by_title, order( 'name desc' ) ### depreciated ??? - use by_name
38
+
39
+
40
+ end # class Tag
41
+
42
+
43
+ end # module TagDb
44
+ end # module Model
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ module TagDb
4
+ module Model
5
+
6
+
7
+ class Tagging < ActiveRecord::Base
8
+
9
+ belongs_to :tag
10
+ belongs_to :taggable, :polymorphic => true
11
+
12
+ end # class Tagging
13
+
14
+
15
+ end # module TagDb
16
+ end # module Model
@@ -11,22 +11,29 @@ create_table :tags do |t|
11
11
  t.string :slug, null: false
12
12
  t.string :name # todo: make required? -- note: was title formerly
13
13
  t.integer :grade, null: false, default: 1 # grade/tier e.g. 1/2/3 for now
14
+
14
15
  ## todo: add parent or similar for hierachy (for tag stacks/packs)
15
- t.timestamps # todo: use only t.datetime :created_at (do we get ar magic? is updated used/needed??)
16
+
17
+ # todo: use only t.datetime :created_at (do we get ar magic? is updated used/needed??)
18
+ t.timestamps
16
19
  end
17
20
 
18
21
  add_index :tags, :key, unique: true
19
22
 
20
23
  create_table :taggings do |t|
21
24
  t.references :tag, null: false
22
- t.references :taggable, polymorphic: true
23
- t.timestamps # todo: use only t.datetime :created_at (do we get ar magic? is updated used/needed??)
25
+ t.references :taggable, null: false, polymorphic: true
26
+
27
+ # todo: use only t.datetime :created_at (do we get ar magic? is updated used/needed??)
28
+ t.timestamps
24
29
  end
25
30
 
26
31
  add_index :taggings, :tag_id
27
32
  add_index :taggings, [:taggable_id, :taggable_type]
33
+ add_index :taggings, [:taggable_id, :taggable_type, :tag_id], unique: true
34
+
35
+ end # method up
28
36
 
29
- end
30
37
 
31
38
  def down
32
39
  raise ActiveRecord::IrreversibleMigration
@@ -1,5 +1,4 @@
1
1
 
2
2
  module TagUtils
3
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1'
4
4
  end
5
-
@@ -0,0 +1,82 @@
1
+
2
+ ## $:.unshift(File.dirname(__FILE__))
3
+
4
+ ## minitest setup
5
+
6
+ # require 'minitest/unit'
7
+ require 'minitest/autorun'
8
+
9
+ # include MiniTest::Unit # lets us use TestCase instead of MiniTest::Unit::TestCase
10
+
11
+
12
+ # ruby stdlibs
13
+
14
+ require 'json'
15
+ require 'uri'
16
+ require 'pp'
17
+ require 'logger'
18
+
19
+ # ruby gems
20
+
21
+ require 'active_record'
22
+
23
+ # our own code
24
+
25
+ require 'tagutils'
26
+ require 'logutils/db' # NB: explict require required for LogDb (not automatic)
27
+
28
+
29
+
30
+ Tag = TagDb::Model::Tag
31
+ Tagging = TagDb::Model::Tagging
32
+
33
+
34
+ class Movie < ActiveRecord::Base
35
+ has_many_tags
36
+ end
37
+
38
+ class CreateMovieDb < ActiveRecord::Migration
39
+
40
+ def up
41
+ create_table :movies do |t|
42
+ t.string :key, null: false
43
+ t.string :name, null: false
44
+ t.timestamps
45
+ end
46
+ end # method up
47
+
48
+ def down
49
+ raise ActiveRecord::IrreversibleMigration
50
+ end
51
+
52
+ end # class CreateMovieDb
53
+
54
+
55
+
56
+ def setup_in_memory_db
57
+ # Database Setup & Config
58
+
59
+ db_config = {
60
+ adapter: 'sqlite3',
61
+ database: ':memory:'
62
+ }
63
+
64
+ pp db_config
65
+
66
+ ActiveRecord::Base.logger = Logger.new( STDOUT )
67
+ ## ActiveRecord::Base.colorize_logging = false - no longer exists - check new api/config setting?
68
+
69
+ ## NB: every connect will create a new empty in memory db
70
+ ActiveRecord::Base.establish_connection( db_config )
71
+
72
+
73
+ ## build schema
74
+
75
+ LogDb.create
76
+ TagDb.create
77
+ CreateMovieDb.new.up
78
+
79
+ end
80
+
81
+
82
+ setup_in_memory_db()
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ class TestModels < MiniTest::Unit::TestCase
6
+
7
+ def setup
8
+ TagDb.delete!
9
+ end
10
+
11
+ def test_count
12
+ assert_equal 0, Tag.count
13
+ assert_equal 0, Tagging.count
14
+ assert_equal 0, Movie.count
15
+ end
16
+
17
+ def test_assocs
18
+ tag = Tag.new( key: 'key', name: 'name' )
19
+ assert_equal 0, tag.taggings.count
20
+
21
+ movie = Movie.new( key: 'key', name: 'name' )
22
+ assert_equal 0, movie.taggings.count
23
+ assert_equal 0, movie.tags.count
24
+
25
+ tag.save!
26
+ movie.save!
27
+
28
+ assert_equal 0, tag.taggings.count
29
+
30
+ assert_equal 0, movie.taggings.count
31
+ assert_equal 0, movie.tags.count
32
+
33
+ ## note: add tag; op << will auto-save
34
+ movie.tags << tag
35
+
36
+ assert_equal 1, tag.taggings.count
37
+ assert_equal 1, movie.taggings.count
38
+ assert_equal 1, movie.tags.count
39
+ end
40
+
41
+ end # class TestModels
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tagutils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,20 +11,31 @@ bindir: bin
11
11
  cert_chain: []
12
12
  date: 2014-03-08 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &72493260 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *72493260
14
25
  - !ruby/object:Gem::Dependency
15
26
  name: logutils
16
- requirement: &74247220 !ruby/object:Gem::Requirement
27
+ requirement: &72492220 !ruby/object:Gem::Requirement
17
28
  none: false
18
29
  requirements:
19
30
  - - ! '>='
20
31
  - !ruby/object:Gem::Version
21
- version: '0.5'
32
+ version: '0.6'
22
33
  type: :runtime
23
34
  prerelease: false
24
- version_requirements: *74247220
35
+ version_requirements: *72492220
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: rdoc
27
- requirement: &74246900 !ruby/object:Gem::Requirement
38
+ requirement: &72582430 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ~>
@@ -32,10 +43,10 @@ dependencies:
32
43
  version: '3.10'
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *74246900
46
+ version_requirements: *72582430
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: hoe
38
- requirement: &74246500 !ruby/object:Gem::Requirement
49
+ requirement: &72582120 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ~>
@@ -43,9 +54,9 @@ dependencies:
43
54
  version: '3.3'
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *74246500
57
+ version_requirements: *72582120
47
58
  description: tagutils - tag utilities (tag, taggings, tag list, etc.)
48
- email: webslideshow@googlegroups.com
59
+ email: openmundi@googlegroups.com
49
60
  executables: []
50
61
  extensions: []
51
62
  extra_rdoc_files:
@@ -56,9 +67,14 @@ files:
56
67
  - README.md
57
68
  - Rakefile
58
69
  - lib/tagutils.rb
59
- - lib/tagutils/models.rb
70
+ - lib/tagutils/active_record.rb
71
+ - lib/tagutils/models/tag.rb
72
+ - lib/tagutils/models/tagging.rb
60
73
  - lib/tagutils/schema.rb
61
74
  - lib/tagutils/version.rb
75
+ - test/helper.rb
76
+ - test/test_models.rb
77
+ - .gemtest
62
78
  homepage: https://github.com/rubylibs/tagutils
63
79
  licenses:
64
80
  - Public Domain
@@ -86,4 +102,5 @@ rubygems_version: 1.8.17
86
102
  signing_key:
87
103
  specification_version: 3
88
104
  summary: tagutils - tag utilities (tag, taggings, tag list, etc.)
89
- test_files: []
105
+ test_files:
106
+ - test/test_models.rb
@@ -1,28 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TagDb
4
- module Model
5
-
6
-
7
- class Tag < ActiveRecord::Base
8
-
9
- ###########################################################################3
10
- # alias for name (remove! add depreciated api call) ?? why? why not??
11
- def title() name; end
12
- def title=(value) self.name = value; end
13
-
14
- end # class Tag
15
-
16
-
17
- class Tagging < ActiveRecord::Base
18
- # add code here
19
- end # class Tagging
20
-
21
-
22
-
23
- end # module Model
24
-
25
- ##### add convenience module alias in plural e.g. lets you use include TagDb::Models
26
- Models = Model
27
-
28
- end # module TagDb