class-table-inheritance 1.2.1 → 1.3.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.
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ test/cti_plugin.sqlite3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in correios.gemspec
4
+ gemspec
data/README CHANGED
@@ -1,9 +1,17 @@
1
+ Change log
2
+ ==========
3
+
4
+ * Now you can inherits from and to modules like inherits_from 'Module::Model', see the the name of field
5
+ must be module_model_id:integer thanks for Marc Remolt (https://github.com/mremolt).
6
+ * Unit test
7
+
8
+
1
9
  Versions
2
10
  ========
3
11
 
4
12
  If you are using Rails 2.3.8 or other version < 3, you have to use the version 1.1.x of this plugin, for Rails 3 you need to use the version 1.2.x or master of this plugin.
5
13
 
6
- ClassTableInheritance 1.2.0
14
+ ClassTableInheritance 1.2.1
7
15
  ===========================
8
16
 
9
17
  This is an ActiveRecord plugin designed to allow
@@ -23,14 +31,14 @@ Example
23
31
 
24
32
  # Migrations
25
33
 
26
- create_table :product do |t|
34
+ create_table :products do |t|
27
35
  t.string :description, :null => false
28
36
  t.string :subtype # Only if you need access of both side see example
29
37
  t.decimal :price
30
38
  t.timestamps
31
39
  end
32
40
 
33
- create_table :book, :inherits => :product do |t|
41
+ create_table :books, :inherits => :product do |t|
34
42
  t.string :author, :null => false
35
43
  end
36
44
 
@@ -39,6 +47,7 @@ Example
39
47
  t.string :genre, :null => false
40
48
  end
41
49
 
50
+
42
51
  # Models
43
52
 
44
53
  class Product < ActiveRecord::Base
@@ -69,6 +78,28 @@ Example
69
78
  book.author = "Shakespeare, William"
70
79
  book.price => 14.00
71
80
  book.save
81
+
82
+
83
+ Module inheritance
84
+ ==================
85
+ # Migrations
86
+
87
+ create_table :mod_users do |t|
88
+ t.string :name, :null => false
89
+ end
90
+
91
+ create_table :managers, :inherits => 'Mod::User' do |t|
92
+ t.string :salary, :null => false
93
+ end
94
+
95
+ # Models
96
+
97
+ class Mod::User < ActiveRecord::Base
98
+ end
99
+
100
+ class Manager < ActiveRecord::Base
101
+ inherits_from 'Mod::User'
102
+ end
72
103
 
73
104
  Top-down access (Polymorphic)
74
105
  =============================
data/Rakefile CHANGED
@@ -1,23 +1,11 @@
1
- require 'rake'
1
+ require 'bundler'
2
2
  require 'rake/testtask'
3
- require 'rake/rdoctask'
3
+ Bundler::GemHelper.install_tasks
4
4
 
5
- desc 'Default: run unit tests.'
6
- task :default => :test
7
-
8
- desc 'Test the class_table_inheritance plugin.'
9
- Rake::TestTask.new(:test) do |t|
5
+ # just 'rake test'
6
+ Rake::TestTask.new do |t|
10
7
  t.libs << 'lib'
11
8
  t.libs << 'test'
12
9
  t.pattern = 'test/**/*_test.rb'
13
10
  t.verbose = true
14
- end
15
-
16
- desc 'Generate documentation for the class_table_inheritance plugin.'
17
- Rake::RDocTask.new(:rdoc) do |rdoc|
18
- rdoc.rdoc_dir = 'rdoc'
19
- rdoc.title = 'ClassTableInheritance'
20
- rdoc.options << '--line-numbers' << '--inline-source'
21
- rdoc.rdoc_files.include('README')
22
- rdoc.rdoc_files.include('lib/**/*.rb')
23
- end
11
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'class-table-inheritance/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "class-table-inheritance"
7
+ s.version = ClassTableInheritance::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Bruno Frank"]
10
+ s.email = ["bfscordeiro@gmail.com"]
11
+ s.homepage = "https://github.com/brunofrank/class-table-inheritance"
12
+ s.summary = %q{ActiveRecord plugin designed to allow simple multiple table (class) inheritance.}
13
+ s.description = %q{ActiveRecord plugin designed to allow simple multiple table (class) inheritance.}
14
+
15
+ s.rubyforge_project = "class-table-inheritance"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -1,141 +1,3 @@
1
1
  require 'active_record'
2
- require 'inherits-migration'
3
-
4
- # ClassTableInheritance is an ActiveRecord plugin designed to allow
5
- # simple multiple table (class) inheritance.
6
- class ActiveRecord::Base
7
- attr_reader :reflection
8
-
9
- def self.acts_as_superclass
10
- if self.column_names.include?("subtype")
11
- def self.find(*args)
12
- super_classes = super
13
- begin
14
- if super_classes.kind_of? Array
15
- super_classes.map do |item|
16
- if !item.subtype.nil? && !item.subtype.blank?
17
- inherits_type = Object.const_get(item.subtype.to_s)
18
- inherits_type.send(:find, item.id)
19
- else
20
- super_classes
21
- end
22
- end
23
- else
24
- if !super_classes.subtype.nil? && !super_classes.subtype.blank?
25
- inherits_type = Object.const_get(super_classes.subtype.to_s)
26
- inherits_type.send(:find, *args)
27
- else
28
- super_classes
29
- end
30
- end
31
- rescue
32
- super_classes
33
- end
34
- end
35
- end
36
- end
37
-
38
- def self.inherits_from(association_id)
39
-
40
- # add an association, and set the foreign key.
41
- has_one association_id, :foreign_key => :id, :dependent => :destroy
42
-
43
-
44
- # set the primary key, it' need because the generalized table doesn't have
45
- # a field ID.
46
- set_primary_key "#{association_id}_id"
47
-
48
-
49
- # Autobuild method to make a instance of association
50
- define_method("#{association_id}_with_autobuild") do
51
- send("#{association_id}_without_autobuild") || send("build_#{association_id}")
52
- end
53
-
54
-
55
- # Set a method chain whith autobuild.
56
- alias_method_chain association_id, :autobuild
57
-
58
-
59
- # bind the before save, this method call the save of association, and
60
- # get our generated ID an set to association_id field.
61
- before_save :save_inherit
62
-
63
-
64
- # Bind the validation of association.
65
- validate :inherit_association_must_be_valid
66
-
67
- # Generate a method to validate the field of association.
68
- define_method("inherit_association_must_be_valid") do
69
- association = send(association_id)
70
-
71
- unless valid = association.valid?
72
- association.errors.each do |attr, message|
73
- errors.add(attr, message)
74
- end
75
- end
76
-
77
- valid
78
- end
79
-
80
-
81
-
82
- # get the class of association by reflection, this is needed because
83
- # i need to get the methods and attributes to make a proxy methods.
84
- reflection = create_reflection(:has_one, association_id, {}, self)
85
- association_class = Object.const_get(reflection.class_name)
86
- # Get the colluns of association class.
87
- inherited_columns = association_class.column_names
88
- # Make a filter in association colluns to exclude the colluns that
89
- # the generalized class already have.
90
- inherited_columns = inherited_columns.reject { |c| self.column_names.grep(c).length > 0 || c == "type" || c == "subtype"}
91
- # Get the methods of the association class and tun it to an Array of Strings.
92
- inherited_methods = association_class.reflections.map { |key,value| key.to_s }
93
- # Make a filter in association methods to exclude the methods that
94
- # the generalizae class already have.
95
- inherited_methods = inherited_methods.reject { |c| self.reflections.map {|key, value| key.to_s }.include?(c) }
96
-
97
-
98
- # create the proxy methods to get and set the properties and methods
99
- # in association class.
100
- (inherited_columns + inherited_methods).each do |name|
101
- define_method name do
102
- # if the field is ID than i only bind that with the association field.
103
- # this is needed to bypass the overflow problem when the ActiveRecord
104
- # try to get the id to find the association.
105
- if name == 'id'
106
- self["#{association_id}_id"]
107
- else
108
- assoc = send(association_id)
109
- assoc.send(name)
110
- end
111
- end
112
-
113
-
114
- define_method "#{name}=" do |new_value|
115
- # if the field is ID than i only bind that with the association field.
116
- # this is needed to bypass the overflow problem when the ActiveRecord
117
- # try to get the id to find the association.
118
- if name == 'id'
119
- self["#{association_id}_id"] = new_value
120
- else
121
- assoc = send(association_id)
122
- assoc.send("#{name}=", new_value)
123
- end
124
- end
125
- end
126
-
127
-
128
- # Create a method do bind in before_save callback, this method
129
- # only call the save of association class and set the id in the
130
- # generalized class.
131
- define_method("save_inherit") do |*args|
132
- association = send(association_id)
133
- if association.attribute_names.include?("subtype")
134
- association.subtype = self.class.to_s
135
- end
136
- association.save
137
- self["#{association_id}_id"] = association.id
138
- true
139
- end
140
- end
141
- end
2
+ require 'class-table-inheritance/inherits-migration'
3
+ require 'class-table-inheritance/class-table-inheritance'
@@ -0,0 +1,145 @@
1
+
2
+ # ClassTableInheritance is an ActiveRecord plugin designed to allow
3
+ # simple multiple table (class) inheritance.
4
+ class ActiveRecord::Base
5
+ attr_reader :reflection
6
+
7
+ def self.acts_as_superclass
8
+ if self.column_names.include?("subtype")
9
+ def self.find(*args)
10
+ super_classes = super
11
+ begin
12
+ if super_classes.kind_of? Array
13
+ super_classes.map do |item|
14
+ if !item.subtype.nil? && !item.subtype.blank?
15
+ inherits_type = super_classes.subtype.to_s.classify.constantize
16
+ inherits_type.send(:find, item.id)
17
+ else
18
+ super_classes
19
+ end
20
+ end
21
+ else
22
+ if !super_classes.subtype.nil? && !super_classes.subtype.blank?
23
+ inherits_type = super_classes.subtype.to_s.classify.constantize
24
+ inherits_type.send(:find, *args)
25
+ else
26
+ super_classes
27
+ end
28
+ end
29
+ rescue
30
+ super_classes
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def self.inherits_from(association_id)
37
+ # Subst the module simbol to dash and if this is string
38
+ if association_id.kind_of?(String)
39
+ class_name = association_id
40
+ association_id = association_id.to_s.gsub(/::/, '_').downcase.to_sym
41
+ else
42
+ class_name = association_id.to_s.classify
43
+ end
44
+
45
+ # add an association, and set the foreign key.
46
+ has_one association_id, :class_name => class_name, :foreign_key => :id, :dependent => :destroy
47
+
48
+
49
+ # set the primary key, it' need because the generalized table doesn't have
50
+ # a field ID.
51
+ set_primary_key "#{association_id}_id"
52
+
53
+
54
+ # Autobuild method to make a instance of association
55
+ define_method("#{association_id}_with_autobuild") do
56
+ send("#{association_id}_without_autobuild") || send("build_#{association_id}")
57
+ end
58
+
59
+
60
+ # Set a method chain whith autobuild.
61
+ alias_method_chain association_id, :autobuild
62
+
63
+
64
+ # bind the before save, this method call the save of association, and
65
+ # get our generated ID an set to association_id field.
66
+ before_save :save_inherit
67
+
68
+
69
+ # Bind the validation of association.
70
+ validate :inherit_association_must_be_valid
71
+
72
+ # Generate a method to validate the field of association.
73
+ define_method("inherit_association_must_be_valid") do
74
+ association = send(association_id)
75
+
76
+ unless valid = association.valid?
77
+ association.errors.each do |attr, message|
78
+ errors.add(attr, message)
79
+ end
80
+ end
81
+
82
+ valid
83
+ end
84
+
85
+
86
+
87
+ # get the class of association by reflection, this is needed because
88
+ # i need to get the methods and attributes to make a proxy methods.
89
+ association_class = class_name.constantize
90
+ # Get the colluns of association class.
91
+ inherited_columns = association_class.column_names
92
+ # Make a filter in association colluns to exclude the colluns that
93
+ # the generalized class already have.
94
+ inherited_columns = inherited_columns.reject { |c| self.column_names.grep(c).length > 0 || c == "type" || c == "subtype"}
95
+ # Get the methods of the association class and tun it to an Array of Strings.
96
+ inherited_methods = association_class.reflections.map { |key,value| key.to_s }
97
+ # Make a filter in association methods to exclude the methods that
98
+ # the generalizae class already have.
99
+ inherited_methods = inherited_methods.reject { |c| self.reflections.map {|key, value| key.to_s }.include?(c) }
100
+
101
+
102
+ # create the proxy methods to get and set the properties and methods
103
+ # in association class.
104
+ (inherited_columns + inherited_methods).each do |name|
105
+ define_method name do
106
+ # if the field is ID than i only bind that with the association field.
107
+ # this is needed to bypass the overflow problem when the ActiveRecord
108
+ # try to get the id to find the association.
109
+ if name == 'id'
110
+ self["#{association_id}_id"]
111
+ else
112
+ assoc = send(association_id)
113
+ assoc.send(name)
114
+ end
115
+ end
116
+
117
+
118
+ define_method "#{name}=" do |new_value|
119
+ # if the field is ID than i only bind that with the association field.
120
+ # this is needed to bypass the overflow problem when the ActiveRecord
121
+ # try to get the id to find the association.
122
+ if name == 'id'
123
+ self["#{association_id}_id"] = new_value
124
+ else
125
+ assoc = send(association_id)
126
+ assoc.send("#{name}=", new_value)
127
+ end
128
+ end
129
+ end
130
+
131
+
132
+ # Create a method do bind in before_save callback, this method
133
+ # only call the save of association class and set the id in the
134
+ # generalized class.
135
+ define_method("save_inherit") do |*args|
136
+ association = send(association_id)
137
+ if association.attribute_names.include?("subtype")
138
+ association.subtype = self.class.to_s
139
+ end
140
+ association.save
141
+ self["#{association_id}_id"] = association.id
142
+ true
143
+ end
144
+ end
145
+ end
@@ -1,4 +1,3 @@
1
- require 'active_record'
2
1
 
3
2
  module InheritsMigration
4
3
 
@@ -14,19 +13,24 @@ module InheritsMigration
14
13
 
15
14
  create_table_without_inherits(table_name, options) do |table_defintion|
16
15
  if options[:inherits]
17
- association_type = Object.const_get(options[:inherits].to_s.capitalize)
16
+ if options[:inherits].kind_of?(String)
17
+ column_to_create = options[:inherits].gsub(/::/, '_').downcase
18
+ association_type = options[:inherits].constantize
19
+ else
20
+ column_to_create = options[:inherits]
21
+ association_type = options[:inherits].to_s.classify.constantize
22
+ end
18
23
  association_inst = association_type.send(:new)
19
24
  attr_column = association_inst.column_for_attribute(association_type.primary_key)
20
25
 
21
26
  field_option = {:primary_key => true, :null => false}
22
27
  field_option[:limit] = attr_column.limit if attr_column.limit
23
- table_defintion.column "#{options[:inherits]}_id", attr_column.type, field_option
28
+ table_defintion.column "#{column_to_create}_id", attr_column.type, field_option
24
29
  end
25
30
  yield table_defintion
26
31
  end
27
32
  end
28
33
  end
29
34
 
30
- #ActiveRecord::ConnectionAdapters::SchemaStatements::send(:include, InheritsMigration)
31
35
  ActiveRecord::Base
32
36
  ActiveRecord::ConnectionAdapters::SchemaStatements::send(:include, InheritsMigration)
@@ -0,0 +1,3 @@
1
+ class ClassTableInheritance
2
+ VERSION = "1.3.0"
3
+ end
@@ -0,0 +1,71 @@
1
+ require 'test_helper'
2
+
3
+ class ClassTableInheritanceTest < Test::Unit::TestCase
4
+
5
+ def test_create
6
+ name = 'Bike'
7
+
8
+ product = Product.new
9
+ product.name = name
10
+ assert_equal true, product.save
11
+
12
+ product = Product.find product.id
13
+ assert_equal name, product.name
14
+ end
15
+
16
+
17
+ def test_inheritance_book
18
+ title = 'Atlas Shrugged'
19
+ isbn = '9780451191144'
20
+
21
+ book = Book.new
22
+ book.name = title
23
+ book.isbn = isbn
24
+ assert_equal true, book.save
25
+
26
+ book = Book.find book.id
27
+ assert_equal title, book.name
28
+ assert_equal isbn, book.isbn
29
+ end
30
+
31
+ def test_inheritance_video
32
+ name = 'Amy Whinehouse - Rehab'
33
+ url = 'http://www.youtube.com/watch?v=3QI8RjKibyc'
34
+
35
+ video = Mod::Video.new
36
+ video.name = name
37
+ video.url = url
38
+ assert_equal true, video.save
39
+
40
+ video = Mod::Video.find video.id
41
+ assert_equal name, video.name
42
+ assert_equal url, video.url
43
+ end
44
+
45
+ def test_inheritance_user_save
46
+ name = 'bfscordeiro'
47
+
48
+ user = Mod::User.new
49
+ user.name = name
50
+ assert_equal true, user.save
51
+
52
+ user = Mod::User.find user.id
53
+ assert_equal name, user.name
54
+ end
55
+
56
+ def test_inheritance_manager_save
57
+ name = 'bfscordeiro'
58
+ salary = '6000'
59
+
60
+ manager = Manager.new
61
+ manager.name = name
62
+ manager.salary = salary
63
+ assert_equal true, manager.save
64
+
65
+ manager = Manager.find manager.id
66
+ assert_equal name, manager.name
67
+ assert_equal salary, manager.salary
68
+ end
69
+
70
+
71
+ end
@@ -0,0 +1,4 @@
1
+ sqlite3:
2
+ :adapter: sqlite3
3
+ :database: test/cti_plugin.sqlite3
4
+
@@ -0,0 +1,3 @@
1
+ class Book < ActiveRecord::Base
2
+ inherits_from :product
3
+ end
@@ -0,0 +1,3 @@
1
+ class Manager < ActiveRecord::Base
2
+ inherits_from 'Mod::User'
3
+ end
@@ -0,0 +1,5 @@
1
+ module Mod
2
+ def self.table_name_prefix
3
+ 'mod_'
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ class Mod::User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,3 @@
1
+ class Mod::Video < ActiveRecord::Base
2
+ inherits_from :product
3
+ end
@@ -0,0 +1,2 @@
1
+ class Product < ActiveRecord::Base
2
+ end
@@ -0,0 +1,24 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :products, :force => true do |t|
3
+ t.string :name
4
+ end
5
+
6
+ create_table :books, :force => true do |t|
7
+ t.string :isbn
8
+ t.integer :product_id
9
+ end
10
+
11
+ create_table :mod_videos, :force => true do |t|
12
+ t.integer :product_id
13
+ t.string :url
14
+ end
15
+
16
+ create_table :mod_users, :force => true do |t|
17
+ t.string :name
18
+ end
19
+
20
+ create_table :managers, :force => true do |t|
21
+ t.integer :mod_user_id
22
+ t.string :salary
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_record'
4
+ require 'class-table-inheritance'
5
+ require 'yaml'
6
+
7
+ database = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
8
+ ActiveRecord::Base.establish_connection(database['sqlite3'])
9
+ load(File.dirname(__FILE__) + "/schema.rb") if !File.exists?(database['sqlite3'][:database])
10
+
11
+ require 'models/product'
12
+ require 'models/book'
13
+ require 'models/mod'
14
+ require 'models/mod/video'
15
+ require 'models/mod/user'
16
+ require 'models/manager'
metadata CHANGED
@@ -1,45 +1,51 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class-table-inheritance
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 2
9
- - 1
10
- version: 1.2.1
4
+ prerelease:
5
+ version: 1.3.0
11
6
  platform: ruby
12
7
  authors:
13
- - Bruno Frank Cordeiro
8
+ - Bruno Frank
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2010-12-03 00:00:00 -02:00
13
+ date: 2011-07-25 00:00:00 -03:00
19
14
  default_executable:
20
15
  dependencies: []
21
16
 
22
- description: ActiveRecord plugin designed to allow simple multiple table inheritance CTI.
23
- email: bfscordeiro@gmail.com
17
+ description: ActiveRecord plugin designed to allow simple multiple table (class) inheritance.
18
+ email:
19
+ - bfscordeiro@gmail.com
24
20
  executables: []
25
21
 
26
22
  extensions: []
27
23
 
28
- extra_rdoc_files:
29
- - README
24
+ extra_rdoc_files: []
25
+
30
26
  files:
31
- - class-table-inheritance-1.0.0.gem
32
- - class-table-inheritance-1.1.0.gem
33
- - class-table-inheritance-1.1.1.gem
34
- - class-table-inheritance-1.2.0.gem
35
- - class-table-inheritance-1.2.1.gem
27
+ - .gitignore
28
+ - Gemfile
29
+ - README
30
+ - Rakefile
31
+ - class-table-inheritance.gemspec
36
32
  - init.rb
37
33
  - lib/class-table-inheritance.rb
38
- - lib/inherits-migration.rb
39
- - Rakefile
40
- - README
34
+ - lib/class-table-inheritance/class-table-inheritance.rb
35
+ - lib/class-table-inheritance/inherits-migration.rb
36
+ - lib/class-table-inheritance/version.rb
37
+ - test/class_table_inheritance_test.rb
38
+ - test/database.yml
39
+ - test/models/book.rb
40
+ - test/models/manager.rb
41
+ - test/models/mod.rb
42
+ - test/models/mod/user.rb
43
+ - test/models/mod/video.rb
44
+ - test/models/product.rb
45
+ - test/schema.rb
46
+ - test/test_helper.rb
41
47
  has_rdoc: true
42
- homepage:
48
+ homepage: https://github.com/brunofrank/class-table-inheritance
43
49
  licenses: []
44
50
 
45
51
  post_install_message:
@@ -52,25 +58,28 @@ required_ruby_version: !ruby/object:Gem::Requirement
52
58
  requirements:
53
59
  - - ">="
54
60
  - !ruby/object:Gem::Version
55
- hash: 3
56
- segments:
57
- - 0
58
61
  version: "0"
59
62
  required_rubygems_version: !ruby/object:Gem::Requirement
60
63
  none: false
61
64
  requirements:
62
65
  - - ">="
63
66
  - !ruby/object:Gem::Version
64
- hash: 3
65
- segments:
66
- - 0
67
67
  version: "0"
68
68
  requirements: []
69
69
 
70
- rubyforge_project:
71
- rubygems_version: 1.3.7
70
+ rubyforge_project: class-table-inheritance
71
+ rubygems_version: 1.6.2
72
72
  signing_key:
73
73
  specification_version: 3
74
- summary: ActiveRecord plugin designed to allow simple multiple table (class) inheritance.
75
- test_files: []
76
-
74
+ summary: ActiveRecord plugin designed to allow simple multiple table (class) inheritance.
75
+ test_files:
76
+ - test/class_table_inheritance_test.rb
77
+ - test/database.yml
78
+ - test/models/book.rb
79
+ - test/models/manager.rb
80
+ - test/models/mod.rb
81
+ - test/models/mod/user.rb
82
+ - test/models/mod/video.rb
83
+ - test/models/product.rb
84
+ - test/schema.rb
85
+ - test/test_helper.rb