eav_hashes 1.0.1 → 1.0.2

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -20
  3. data/README.md +147 -147
  4. data/Rakefile +30 -30
  5. data/lib/eav_hashes/activerecord_extension.rb +37 -37
  6. data/lib/eav_hashes/eav_entry.rb +128 -128
  7. data/lib/eav_hashes/eav_hash.rb +167 -167
  8. data/lib/eav_hashes/util.rb +122 -122
  9. data/lib/eav_hashes/version.rb +5 -5
  10. data/lib/eav_hashes.rb +8 -8
  11. data/lib/generators/eav_migration/USAGE +26 -26
  12. data/lib/generators/eav_migration/eav_migration.rb +35 -35
  13. data/lib/generators/eav_migration/templates/eav_migration.erb +15 -15
  14. data/spec/dummy/README.rdoc +261 -261
  15. data/spec/dummy/Rakefile +7 -7
  16. data/spec/dummy/app/assets/javascripts/application.js +15 -15
  17. data/spec/dummy/app/assets/stylesheets/application.css +13 -13
  18. data/spec/dummy/app/controllers/application_controller.rb +3 -3
  19. data/spec/dummy/app/helpers/application_helper.rb +2 -2
  20. data/spec/dummy/app/models/custom_test_object.rb +6 -6
  21. data/spec/dummy/app/models/product.rb +3 -4
  22. data/spec/dummy/app/views/layouts/application.html.erb +14 -14
  23. data/spec/dummy/config/application.rb +62 -68
  24. data/spec/dummy/config/boot.rb +9 -9
  25. data/spec/dummy/config/database.yml +25 -25
  26. data/spec/dummy/config/environment.rb +5 -5
  27. data/spec/dummy/config/environments/development.rb +34 -37
  28. data/spec/dummy/config/environments/production.rb +70 -67
  29. data/spec/dummy/config/environments/test.rb +34 -37
  30. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -7
  31. data/spec/dummy/config/initializers/inflections.rb +15 -15
  32. data/spec/dummy/config/initializers/mime_types.rb +5 -5
  33. data/spec/dummy/config/initializers/secret_token.rb +7 -7
  34. data/spec/dummy/config/initializers/session_store.rb +8 -8
  35. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -14
  36. data/spec/dummy/config/locales/en.yml +5 -5
  37. data/spec/dummy/config/routes.rb +58 -58
  38. data/spec/dummy/config.ru +4 -4
  39. data/spec/dummy/db/migrate/20121206133059_create_products.rb +9 -9
  40. data/spec/dummy/db/migrate/20121210055854_create_product_tech_specs.rb +15 -15
  41. data/spec/dummy/db/seeds.rb +30 -30
  42. data/spec/dummy/public/404.html +26 -26
  43. data/spec/dummy/public/422.html +26 -26
  44. data/spec/dummy/public/500.html +25 -25
  45. data/spec/dummy/script/rails +6 -6
  46. data/spec/lib/eav_hashes/eav_hash_spec.rb +147 -137
  47. data/spec/lib/generators/eav_migration_spec.rb +60 -60
  48. data/spec/spec_helper.rb +24 -24
  49. metadata +25 -44
  50. data/spec/dummy/db/development.sqlite3 +0 -0
  51. data/spec/dummy/db/schema.rb +0 -35
  52. data/spec/dummy/db/test.sqlite3 +0 -0
  53. data/spec/dummy/log/ENV=test.log +0 -1
  54. data/spec/dummy/log/development.log +0 -46
  55. data/spec/dummy/log/test.log +0 -4623
@@ -1,122 +1,122 @@
1
- module ActiveRecord
2
- module EavHashes
3
- module Util
4
- # Sanity checks!
5
- # @param [Hash] options the options hash to check for emptyness and Hashiness
6
- def self.sanity_check(options)
7
- raise "options cannot be empty (and you shouldn't be calling this since you left options blank)" if
8
- (!options.is_a? Hash) or options.empty?
9
- end
10
-
11
- # Fills in any options not explicitly passed to eav_hash_for and creates an EavEntry type for the table
12
- # @param [Hash] options the options hash to be filled with defaults on unset keys.
13
- def self.fill_options_hash(options)
14
- sanity_check options
15
-
16
- # Generate a unique class name based on the eav_hash's name and owner
17
- options[:entry_class_name] ||= "#{options[:parent_class_name]}_#{options[:hash_name]}_entry".camelize.to_sym
18
-
19
- # Strip "_entries" from the table name
20
- if /Entry$/.match options[:entry_class_name]
21
- options[:table_name] ||= options[:entry_class_name].to_s.tableize.slice(0..-9).to_sym
22
- else
23
- options[:table_name] ||= options[:entry_class_name].to_s.tableize.to_sym
24
- end
25
-
26
- # Create the symbol name for the "belongs_to" association in the entry model
27
- options[:parent_assoc_name] ||= "#{options[:parent_class_name].to_s.underscore}".to_sym
28
-
29
- # Create the symbol name for the "has_many" association in the parent model
30
- options[:entry_assoc_name] = options[:entry_class_name].to_s.tableize.to_sym
31
-
32
- # Change slashes to underscores in options to match what's output by the generator
33
- # TODO: Refactor table naming into one location
34
- options[:table_name] = options[:table_name].to_s.gsub(/\//,'_').to_sym
35
- options[:parent_assoc_name] = options[:parent_assoc_name].to_s.gsub(/\//,'_').to_sym
36
- options[:entry_assoc_name] = options[:entry_assoc_name].to_s.gsub(/\//,'_').to_sym
37
-
38
- # Create our custom type if it doesn't exist already
39
- options[:entry_class] = create_eav_table_class options
40
-
41
- return options
42
- end
43
-
44
- # Creates a new type subclassed from ActiveRecord::EavHashes::EavEntry which represents an eav_hash key-value pair
45
- def self.create_eav_table_class (options)
46
- sanity_check options
47
-
48
- # Don't overwrite an existing type
49
- return class_from_string(options[:entry_class_name].to_s) if class_from_string_exists?(options[:entry_class_name])
50
-
51
- # Create our type
52
- klass = set_constant_from_string options[:entry_class_name].to_s, Class.new(ActiveRecord::EavHashes::EavEntry)
53
-
54
- # Fill in the associations and specify the table it belongs to
55
- klass.class_eval <<-END_EVAL
56
- self.table_name = "#{options[:table_name]}"
57
- belongs_to :#{options[:parent_assoc_name]}
58
- END_EVAL
59
-
60
- return klass
61
- end
62
-
63
- # Searches an EavEntry's table for the specified key/value pair and returns an
64
- # array containing the IDs of the models whose eav_hash key/value pair.
65
- # You should not run this directly.
66
- # @param [String, Symbol] key the key to search by
67
- # @param [Object] value the value to search by. if this is nil, it will return all models which contain `key`
68
- # @param [Hash] options the options hash which eav_hash_for hash generated.
69
- def self.run_find_expression (key, value, options)
70
- sanity_check options
71
- raise "Can't search for a nil key!" if key.nil?
72
- if value.nil?
73
- options[:entry_class].where(
74
- "entry_key = ? and symbol_key = ?",
75
- key.to_s,
76
- key.is_a?(Symbol)
77
- ).pluck("#{options[:parent_assoc_name]}_id".to_sym)
78
- else
79
- val_type = EavEntry.get_value_type value
80
- if val_type == EavEntry::SUPPORTED_TYPES[:Object]
81
- raise "Can't search by Objects/Hashes/Arrays!"
82
- else
83
- options[:entry_class].where(
84
- "entry_key = ? and symbol_key = ? and value = ? and value_type = ?",
85
- key.to_s,
86
- key.is_a?(Symbol),
87
- value.to_s,
88
- val_type
89
- ).pluck("#{options[:parent_assoc_name]}_id".to_sym)
90
- end
91
- end
92
- end
93
-
94
- # Find a class even if it's contained in one or more modules.
95
- # See http://stackoverflow.com/questions/3163641/get-a-class-by-name-in-ruby
96
- def self.class_from_string(str)
97
- str.split('::').inject(Object) do |mod, class_name|
98
- mod.const_get(class_name)
99
- end
100
- end
101
-
102
- # Check whether a class exists, even if it's contained in one or more modules.
103
- def self.class_from_string_exists?(str)
104
- begin
105
- class_from_string(str)
106
- rescue
107
- return false
108
- end
109
- true
110
- end
111
-
112
- # Set a constant from a string, even if the string contains modules. Modules
113
- # are created if necessary.
114
- def self.set_constant_from_string(str, val)
115
- parent = str.deconstantize.split('::').inject(Object) do |mod, class_name|
116
- mod.const_defined?(class_name) ? mod.const_get(class_name) : mod.const_set(class_name, Module.new())
117
- end
118
- parent.const_set(str.demodulize.to_sym, val)
119
- end
120
- end
121
- end
122
- end
1
+ module ActiveRecord
2
+ module EavHashes
3
+ module Util
4
+ # Sanity checks!
5
+ # @param [Hash] options the options hash to check for emptyness and Hashiness
6
+ def self.sanity_check(options)
7
+ raise "options cannot be empty (and you shouldn't be calling this since you left options blank)" if
8
+ (!options.is_a? Hash) or options.empty?
9
+ end
10
+
11
+ # Fills in any options not explicitly passed to eav_hash_for and creates an EavEntry type for the table
12
+ # @param [Hash] options the options hash to be filled with defaults on unset keys.
13
+ def self.fill_options_hash(options)
14
+ sanity_check options
15
+
16
+ # Generate a unique class name based on the eav_hash's name and owner
17
+ options[:entry_class_name] ||= "#{options[:parent_class_name]}_#{options[:hash_name]}_entry".camelize.to_sym
18
+
19
+ # Strip "_entries" from the table name
20
+ if /Entry$/.match options[:entry_class_name]
21
+ options[:table_name] ||= options[:entry_class_name].to_s.tableize.slice(0..-9).to_sym
22
+ else
23
+ options[:table_name] ||= options[:entry_class_name].to_s.tableize.to_sym
24
+ end
25
+
26
+ # Create the symbol name for the "belongs_to" association in the entry model
27
+ options[:parent_assoc_name] ||= "#{options[:parent_class_name].to_s.underscore}".to_sym
28
+
29
+ # Create the symbol name for the "has_many" association in the parent model
30
+ options[:entry_assoc_name] = options[:entry_class_name].to_s.tableize.to_sym
31
+
32
+ # Change slashes to underscores in options to match what's output by the generator
33
+ # TODO: Refactor table naming into one location
34
+ options[:table_name] = options[:table_name].to_s.gsub(/\//,'_').to_sym
35
+ options[:parent_assoc_name] = options[:parent_assoc_name].to_s.gsub(/\//,'_').to_sym
36
+ options[:entry_assoc_name] = options[:entry_assoc_name].to_s.gsub(/\//,'_').to_sym
37
+
38
+ # Create our custom type if it doesn't exist already
39
+ options[:entry_class] = create_eav_table_class options
40
+
41
+ return options
42
+ end
43
+
44
+ # Creates a new type subclassed from ActiveRecord::EavHashes::EavEntry which represents an eav_hash key-value pair
45
+ def self.create_eav_table_class (options)
46
+ sanity_check options
47
+
48
+ # Don't overwrite an existing type
49
+ return class_from_string(options[:entry_class_name].to_s) if class_from_string_exists?(options[:entry_class_name])
50
+
51
+ # Create our type
52
+ klass = set_constant_from_string options[:entry_class_name].to_s, Class.new(ActiveRecord::EavHashes::EavEntry)
53
+
54
+ # Fill in the associations and specify the table it belongs to
55
+ klass.class_eval <<-END_EVAL
56
+ self.table_name = "#{options[:table_name]}"
57
+ belongs_to :#{options[:parent_assoc_name]}
58
+ END_EVAL
59
+
60
+ return klass
61
+ end
62
+
63
+ # Searches an EavEntry's table for the specified key/value pair and returns an
64
+ # array containing the IDs of the models whose eav_hash key/value pair.
65
+ # You should not run this directly.
66
+ # @param [String, Symbol] key the key to search by
67
+ # @param [Object] value the value to search by. if this is nil, it will return all models which contain `key`
68
+ # @param [Hash] options the options hash which eav_hash_for hash generated.
69
+ def self.run_find_expression (key, value, options)
70
+ sanity_check options
71
+ raise "Can't search for a nil key!" if key.nil?
72
+ if value.nil?
73
+ options[:entry_class].where(
74
+ "entry_key = ? and symbol_key = ?",
75
+ key.to_s,
76
+ key.is_a?(Symbol)
77
+ ).pluck("#{options[:parent_assoc_name]}_id".to_sym)
78
+ else
79
+ val_type = EavEntry.get_value_type value
80
+ if val_type == EavEntry::SUPPORTED_TYPES[:Object]
81
+ raise "Can't search by Objects/Hashes/Arrays!"
82
+ else
83
+ options[:entry_class].where(
84
+ "entry_key = ? and symbol_key = ? and value = ? and value_type = ?",
85
+ key.to_s,
86
+ key.is_a?(Symbol),
87
+ value.to_s,
88
+ val_type
89
+ ).pluck("#{options[:parent_assoc_name]}_id".to_sym)
90
+ end
91
+ end
92
+ end
93
+
94
+ # Find a class even if it's contained in one or more modules.
95
+ # See http://stackoverflow.com/questions/3163641/get-a-class-by-name-in-ruby
96
+ def self.class_from_string(str)
97
+ str.split('::').inject(Object) do |mod, class_name|
98
+ mod.const_get(class_name)
99
+ end
100
+ end
101
+
102
+ # Check whether a class exists, even if it's contained in one or more modules.
103
+ def self.class_from_string_exists?(str)
104
+ begin
105
+ class_from_string(str)
106
+ rescue
107
+ return false
108
+ end
109
+ true
110
+ end
111
+
112
+ # Set a constant from a string, even if the string contains modules. Modules
113
+ # are created if necessary.
114
+ def self.set_constant_from_string(str, val)
115
+ parent = str.deconstantize.split('::').inject(Object) do |mod, class_name|
116
+ mod.const_defined?(class_name) ? mod.const_get(class_name) : mod.const_set(class_name, Module.new())
117
+ end
118
+ parent.const_set(str.demodulize.to_sym, val)
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,5 +1,5 @@
1
- module ActiveRecord
2
- module EavHashes
3
- VERSION = "1.0.1"
4
- end
5
- end
1
+ module ActiveRecord
2
+ module EavHashes
3
+ VERSION = "1.0.2"
4
+ end
5
+ end
data/lib/eav_hashes.rb CHANGED
@@ -1,8 +1,8 @@
1
- require "eav_hashes/util"
2
- require "eav_hashes/eav_entry"
3
- require "eav_hashes/eav_hash"
4
- require "eav_hashes/activerecord_extension"
5
- require "generators/eav_migration/eav_migration"
6
-
7
- # tally-ho!
8
- ActiveRecord::Base.send :include, ActiveRecord::EavHashes
1
+ require "eav_hashes/util"
2
+ require "eav_hashes/eav_entry"
3
+ require "eav_hashes/eav_hash"
4
+ require "eav_hashes/activerecord_extension"
5
+ require "generators/eav_migration/eav_migration"
6
+
7
+ # tally-ho!
8
+ ActiveRecord::Base.send :include, ActiveRecord::EavHashes
@@ -1,26 +1,26 @@
1
- Description:
2
- Creates a DB migration to generate the schema for a table which is used to
3
- store the entries of an eav_hash.
4
-
5
- Example:
6
- If you're not setting a custom table name, i.e., your model looks like this:
7
-
8
- class ModelName < ActiveRecord::Base
9
- eav_hash_for :hash_name
10
- end
11
-
12
- Then simply run this migration like so:
13
-
14
- rails generate eav_migration ModelName hash_name
15
-
16
- However, if you're a wizard and have specified a custom table name like this:
17
-
18
- class ModelName < ActiveRecord::Base
19
- eav_hash_for :hash_name, :table_name => :custom_table
20
- end
21
-
22
- Then run this generator like this:
23
-
24
- rails generate eav_migration ModelName hash_name custom_table
25
-
26
- Easy as pie!
1
+ Description:
2
+ Creates a DB migration to generate the schema for a table which is used to
3
+ store the entries of an eav_hash.
4
+
5
+ Example:
6
+ If you're not setting a custom table name, i.e., your model looks like this:
7
+
8
+ class ModelName < ActiveRecord::Base
9
+ eav_hash_for :hash_name
10
+ end
11
+
12
+ Then simply run this migration like so:
13
+
14
+ rails generate eav_migration ModelName hash_name
15
+
16
+ However, if you're a wizard and have specified a custom table name like this:
17
+
18
+ class ModelName < ActiveRecord::Base
19
+ eav_hash_for :hash_name, :table_name => :custom_table
20
+ end
21
+
22
+ Then run this generator like this:
23
+
24
+ rails generate eav_migration ModelName hash_name custom_table
25
+
26
+ Easy as pie!
@@ -1,36 +1,36 @@
1
- require 'rails/generators'
2
- require 'rails/generators/active_record'
3
-
4
- class EavMigrationGenerator < ActiveRecord::Generators::Base
5
-
6
- source_root File.expand_path "../templates", __FILE__
7
- # small hack to override NamedBase displaying NAME
8
- argument :name, :required => true, :type => :string, :banner => "<ModelName>"
9
- argument :hash_name, :required => true, :type => :string, :banner => "<hash_name>"
10
- argument :custom_table_name, :required => false, :type => :string, :banner => "table_name"
11
-
12
- def create_eav_migration
13
- p name
14
- migration_template "eav_migration.erb", "db/migrate/#{migration_file_name}.rb"
15
- end
16
-
17
- def migration_file_name
18
- "create_" + table_name
19
- end
20
-
21
- def migration_name
22
- migration_file_name.camelize
23
- end
24
-
25
- def table_name
26
- custom_table_name || "#{name}_#{hash_name}".underscore.gsub(/\//, '_')
27
- end
28
-
29
- def model_name
30
- name
31
- end
32
-
33
- def model_association_name
34
- model_name.underscore.gsub(/\//,'_')
35
- end
1
+ require 'rails/generators'
2
+ require 'rails/generators/active_record'
3
+
4
+ class EavMigrationGenerator < ActiveRecord::Generators::Base
5
+
6
+ source_root File.expand_path "../templates", __FILE__
7
+ # small hack to override NamedBase displaying NAME
8
+ argument :name, :required => true, :type => :string, :banner => "<ModelName>"
9
+ argument :hash_name, :required => true, :type => :string, :banner => "<hash_name>"
10
+ argument :custom_table_name, :required => false, :type => :string, :banner => "table_name"
11
+
12
+ def create_eav_migration
13
+ p name
14
+ migration_template "eav_migration.erb", "db/migrate/#{migration_file_name}.rb"
15
+ end
16
+
17
+ def migration_file_name
18
+ "create_" + table_name
19
+ end
20
+
21
+ def migration_name
22
+ migration_file_name.camelize
23
+ end
24
+
25
+ def table_name
26
+ custom_table_name || "#{name}_#{hash_name}".underscore.gsub(/\//, '_')
27
+ end
28
+
29
+ def model_name
30
+ name
31
+ end
32
+
33
+ def model_association_name
34
+ model_name.underscore.gsub(/\//,'_')
35
+ end
36
36
  end
@@ -1,16 +1,16 @@
1
- class <%= migration_name %> < ActiveRecord::Migration
2
- def change
3
- create_table :<%= table_name %> do |t|
4
- t.references :<%= model_association_name %>, :null => false
5
- t.string :entry_key, :null => false
6
- t.text :value, :null => false
7
- t.integer :value_type, :null => false
8
- t.boolean :symbol_key, :null => false, :default => true
9
-
10
- t.timestamps
11
- end
12
-
13
- add_index :<%= table_name %>, :<%= model_association_name %>_id
14
- add_index :<%= table_name %>, :entry_key
15
- end
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def change
3
+ create_table :<%= table_name %> do |t|
4
+ t.references :<%= model_association_name %>, :null => false
5
+ t.string :entry_key, :null => false
6
+ t.text :value, :null => false
7
+ t.integer :value_type, :null => false
8
+ t.boolean :symbol_key, :null => false, :default => true
9
+
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :<%= table_name %>, :<%= model_association_name %>_id
14
+ add_index :<%= table_name %>, :entry_key
15
+ end
16
16
  end