nobrainer 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 43783bcf0d625af679de685ab771782ce9b141f3
4
- data.tar.gz: 4b5e4ff205f55adb754133b681b6e71c71772790
3
+ metadata.gz: e97dd4f563340a2c8551ffefb21f22fc628954b2
4
+ data.tar.gz: 1fca054e8f966be9e7518f8245c39987d40068c7
5
5
  SHA512:
6
- metadata.gz: 1c182d056390dd2c7b51bac68999d79c72cfaca49837239c4eead56ce8d0ff474630cc7b24e9fa12a4ff8d36641a5f6cc46fb7c588c45e975af42e8d4b5dbebc
7
- data.tar.gz: 5226adb01498de4e82f8b3a4729c818ed1a40dc07e3596061d64956407b9a62129108046e0625bbe60bcac1804f0b8111cab4ec3a736151b6cfdc3d5799f2d88
6
+ metadata.gz: 1cbfebfa6ac2922e733d157522eda4e6c9edf9de9e51601f6892ac2ac2814593ed20807c68441a2ff7391398cf37896eeb739eaf2cdafa0da8e9fe91bb02fce2
7
+ data.tar.gz: ace1719ae85c7593145e81818fb1b93f715ad65d4634130c664b0fdd134c637aba0395066163b9fd3aee91f7ec0b27a53338e857ec2c089a4b425e02f2eba00b
@@ -4,7 +4,8 @@ module NoBrainer::Config
4
4
  class << self
5
5
  mattr_accessor :rethinkdb_url, :logger, :warn_on_active_record,
6
6
  :auto_create_databases, :auto_create_tables,
7
- :max_reconnection_tries, :durability, :colorize_logger,
7
+ :max_reconnection_tries, :durability,
8
+ :user_timezone, :db_timezone, :colorize_logger,
8
9
  :distributed_lock_class
9
10
 
10
11
  def apply_defaults
@@ -15,6 +16,8 @@ module NoBrainer::Config
15
16
  self.auto_create_tables = true
16
17
  self.max_reconnection_tries = 10
17
18
  self.durability = default_durability
19
+ self.user_timezone = :local
20
+ self.db_timezone = :utc
18
21
  self.colorize_logger = true
19
22
  self.distributed_lock_class = nil
20
23
  end
@@ -27,6 +30,7 @@ module NoBrainer::Config
27
30
  def configure(&block)
28
31
  apply_defaults unless configured?
29
32
  block.call(self) if block
33
+ assert_valid_options!
30
34
  @configured = true
31
35
 
32
36
  NoBrainer.disconnect_if_url_changed
@@ -36,6 +40,18 @@ module NoBrainer::Config
36
40
  !!@configured
37
41
  end
38
42
 
43
+ def assert_valid_options!
44
+ assert_array_in :durability, [:hard, :soft]
45
+ assert_array_in :user_timezone, [:unchanged, :utc, :local]
46
+ assert_array_in :db_timezone, [:unchanged, :utc, :local]
47
+ end
48
+
49
+ def assert_array_in(name, values)
50
+ unless __send__(name).in?(values)
51
+ raise ArgumentError.new("Unknown configuration for #{name}: #{__send__(name)}. Valid values are: #{values.inspect}")
52
+ end
53
+ end
54
+
39
55
  def default_rethinkdb_url
40
56
  db = ENV['RETHINKDB_DB'] || ENV['RDB_DB']
41
57
  db ||= "#{Rails.application.class.parent_name.underscore}_#{Rails.env}" rescue nil
@@ -2,7 +2,7 @@ module NoBrainer::Criteria::Count
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  def count
5
- run(to_rql.count)
5
+ run(without_ordering.to_rql.count)
6
6
  end
7
7
 
8
8
  def empty?
@@ -17,6 +17,12 @@ module NoBrainer::Criteria::First
17
17
  last.tap { |doc| raise NoBrainer::Error::DocumentNotFound unless doc }
18
18
  end
19
19
 
20
+ def sample(n=nil)
21
+ result = NoBrainer.run { self.without_ordering.to_rql.sample(n.nil? ? 1 : n) }
22
+ result = result.map(&method(:instantiate_doc))
23
+ n.nil? ? result.first : result
24
+ end
25
+
20
26
  private
21
27
 
22
28
  def get_one(criteria)
@@ -54,24 +54,26 @@ module NoBrainer::Criteria::Where
54
54
  end
55
55
  end
56
56
 
57
- class BinaryOperator < Struct.new(:key, :op, :value, :criteria)
57
+ class BinaryOperator < Struct.new(:key, :op, :value, :criteria, :casted_values)
58
58
  def simplify
59
59
  key = cast_key(self.key)
60
60
  case op
61
61
  when :in then
62
62
  case value
63
- when Range then BinaryOperator.new(key, :between, (cast_value(value.min)..cast_value(value.max)), criteria)
64
- when Array then BinaryOperator.new(key, :in, value.map(&method(:cast_value)).uniq, criteria)
63
+ when Range then BinaryOperator.new(key, :between, (cast_value(value.min)..cast_value(value.max)), criteria, true)
64
+ when Array then BinaryOperator.new(key, :in, value.map(&method(:cast_value)).uniq, criteria, true)
65
65
  else raise ArgumentError.new ":in takes an array/range, not #{value}"
66
66
  end
67
- else BinaryOperator.new(key, op, cast_value(value), criteria)
67
+ when :between then BinaryOperator.new(key, :between, (cast_value(value.min)..cast_value(value.max)), criteria, true)
68
+ else BinaryOperator.new(key, op, cast_value(value), criteria, true)
68
69
  end
69
70
  end
70
71
 
71
72
  def to_rql(doc)
72
73
  case op
74
+ when :defined then value ? doc.has_fields(key) : doc.has_fields(key).not
73
75
  when :between then (doc[key] >= value.min) & (doc[key] <= value.max)
74
- when :in then RethinkDB::RQL.new.expr(value).contains(doc[key])
76
+ when :in then RethinkDB::RQL.new.expr(value).contains(doc[key])
75
77
  else doc[key].__send__(op, value)
76
78
  end
77
79
  end
@@ -87,6 +89,8 @@ module NoBrainer::Criteria::Where
87
89
  end
88
90
 
89
91
  def cast_value(value)
92
+ return value if casted_values
93
+
90
94
  case association
91
95
  when NoBrainer::Document::Association::BelongsTo::Metadata
92
96
  target_klass = association.target_klass
@@ -99,6 +103,8 @@ module NoBrainer::Criteria::Where
99
103
  end
100
104
 
101
105
  def cast_key(key)
106
+ return key if casted_values
107
+
102
108
  case association
103
109
  when NoBrainer::Document::Association::BelongsTo::Metadata
104
110
  association.foreign_key
@@ -2,7 +2,8 @@ class NoBrainer::DecoratedSymbol < Struct.new(:symbol, :modifier, :args)
2
2
  MODIFIERS = { :in => :in, :nin => :nin,
3
3
  :eq => :eq, :ne => :ne, :not => :ne,
4
4
  :gt => :gt, :ge => :ge, :gte => :ge,
5
- :lt => :lt, :le => :le, :lte => :le}
5
+ :lt => :lt, :le => :le, :lte => :le,
6
+ :defined => :defined }
6
7
 
7
8
  def self.hook
8
9
  Symbol.class_eval do
@@ -1,7 +1,5 @@
1
1
  module NoBrainer::Document::Attributes
2
- VALID_FIELD_OPTIONS = [:index, :default, :type, :cast_user_to_db,
3
- :cast_db_to_user, :validates, :required, :unique,
4
- :readonly, :primary_key]
2
+ VALID_FIELD_OPTIONS = [:index, :default, :type, :validates, :required, :unique, :in, :readonly, :primary_key]
5
3
  RESERVED_FIELD_NAMES = [:index, :default, :and, :or, :selector, :associations, :pk_value] \
6
4
  + NoBrainer::DecoratedSymbol::MODIFIERS.keys
7
5
  extend ActiveSupport::Concern
@@ -64,6 +62,10 @@ module NoBrainer::Document::Attributes
64
62
  Hash[@_attributes.sort_by { |k,v| self.class.fields.keys.index(k.to_sym) || 2**10 }]
65
63
  end
66
64
 
65
+ def to_s
66
+ "#<#{self.class} #{self.class.pk_name}: #{self.pk_value.inspect}>"
67
+ end
68
+
67
69
  def inspect
68
70
  "#<#{self.class} #{inspectable_attributes.map { |k,v| "#{k}: #{v.inspect}" }.join(', ')}>"
69
71
  end
@@ -10,7 +10,7 @@ module NoBrainer::Document::Criteria
10
10
  module ClassMethods
11
11
  delegate :to_rql, # Core
12
12
  :limit, :offset, :skip, # Limit
13
- :order_by, :reverse_order, # OrderBy
13
+ :order_by, :reverse_order, :without_ordering, # OrderBy
14
14
  :scoped, :unscoped, # Scope
15
15
  :where, :with_index, :without_index, :used_index, :indexed?, # Where
16
16
  :with_cache, :without_cache, # Cache
@@ -18,7 +18,7 @@ module NoBrainer::Document::Criteria
18
18
  :delete_all, :destroy_all, # Delete
19
19
  :includes, :preload, # Preload
20
20
  :each, :to_a, # Enumerable
21
- :first, :last, :first!, :last!, # First
21
+ :first, :last, :first!, :last!, :sample, # First
22
22
  :update_all, :replace_all, # Update
23
23
  :to => :all
24
24
 
@@ -28,7 +28,7 @@ module NoBrainer::Document::Persistance
28
28
 
29
29
  def _create(options={})
30
30
  return false if options[:validate] && !valid?
31
- keys = self.class.insert_all(@_attributes)
31
+ keys = self.class.insert_all(self.class.persistable_attributes(@_attributes))
32
32
  self.pk_value ||= keys.first
33
33
  @new_record = false
34
34
  true
@@ -50,7 +50,7 @@ module NoBrainer::Document::Persistance
50
50
  attr = RethinkDB::RQL.new.literal(attr) if attr.is_a?(Hash)
51
51
  [k, attr]
52
52
  end]
53
- _update(attrs) if attrs.present?
53
+ _update(self.class.persistable_attributes(attrs)) if attrs.present?
54
54
  true
55
55
  end
56
56
 
@@ -1,102 +1,7 @@
1
1
  module NoBrainer::Document::Types
2
2
  extend ActiveSupport::Concern
3
3
 
4
- module CastUserToDB
5
- extend self
6
- InvalidType = NoBrainer::Error::InvalidType
7
-
8
- def String(value)
9
- case value
10
- when Symbol then value.to_s
11
- else raise InvalidType
12
- end
13
- end
14
-
15
- def Integer(value)
16
- case value
17
- when String
18
- value = value.strip.gsub(/^\+/, '')
19
- value.to_i.tap { |new_value| new_value.to_s == value or raise InvalidType }
20
- when Float
21
- value.to_i.tap { |new_value| new_value.to_f == value or raise InvalidType }
22
- else raise InvalidType
23
- end
24
- end
25
-
26
- def Float(value)
27
- case value
28
- when Integer then value.to_f
29
- when String
30
- value = value.strip.gsub(/^\+/, '')
31
- value = value.gsub(/0+$/, '') if value['.']
32
- value = value.gsub(/\.$/, '')
33
- value = "#{value}.0" unless value['.']
34
- value.to_f.tap { |new_value| new_value.to_s == value or raise InvalidType }
35
- else raise InvalidType
36
- end
37
- end
38
-
39
- def Boolean(value)
40
- case value
41
- when TrueClass then true
42
- when FalseClass then false
43
- when String, Integer
44
- value = value.to_s.strip.downcase
45
- return true if value.in? %w(true yes t 1)
46
- return false if value.in? %w(false no f 0)
47
- raise InvalidType
48
- else raise InvalidType
49
- end
50
- end
51
-
52
- def Symbol(value)
53
- case value
54
- when String
55
- value = value.strip
56
- raise InvalidType if value.empty?
57
- value.to_sym
58
- else raise InvalidType
59
- end
60
- end
61
-
62
- def lookup(type)
63
- public_method(type.to_s)
64
- rescue NameError
65
- proc { raise InvalidType }
66
- end
67
- end
68
-
69
- module CastDBToUser
70
- extend self
71
-
72
- def Symbol(value)
73
- value.to_sym rescue value
74
- end
75
-
76
- def lookup(type)
77
- public_method(type.to_s)
78
- rescue NameError
79
- nil
80
- end
81
- end
82
-
83
- included do
84
- # We namespace our fake Boolean class to avoid polluting the global namespace
85
- class_exec do
86
- class Boolean
87
- def initialize; raise; end
88
- def self.inspect; 'Boolean'; end
89
- def self.to_s; inspect; end
90
- def self.name; inspect; end
91
- end
92
- end
93
- before_validation :add_type_errors
94
-
95
- # Fast access for db->user cast methods for performance when reading from
96
- # the database.
97
- singleton_class.send(:attr_accessor, :cast_db_to_user_fields)
98
- self.cast_db_to_user_fields = Set.new
99
- end
4
+ included { before_validation :add_type_errors }
100
5
 
101
6
  def add_type_errors
102
7
  return unless @pending_type_errors
@@ -108,49 +13,59 @@ module NoBrainer::Document::Types
108
13
  def assign_attributes(attrs, options={})
109
14
  super
110
15
  if options[:from_db]
111
- self.class.cast_db_to_user_fields.each do |attr|
112
- field_def = self.class.fields[attr]
113
- type = field_def[:type]
114
- value = @_attributes[attr.to_s]
115
- unless value.nil? || value.is_a?(type)
116
- @_attributes[attr.to_s] = field_def[:cast_db_to_user].call(value)
117
- end
118
- end
16
+ @_attributes = Hash[@_attributes.map do |k,v|
17
+ [k, self.class.cast_db_to_model_for(k, v)]
18
+ end].with_indifferent_access
119
19
  end
120
20
  end
121
21
 
122
22
  module ClassMethods
123
- def cast_user_to_db_for(attr, value)
124
- field_def = fields[attr.to_sym]
125
- return value if !field_def
126
- type = field_def[:type]
127
- return value if value.nil? || type.nil? || value.is_a?(type)
128
- field_def[:cast_user_to_db].call(value)
23
+ def cast_user_to_model_for(attr, value)
24
+ type = fields[attr.to_sym].try(:[], :type)
25
+ return value if type.nil? || value.nil?
26
+ if type.respond_to?(:nobrainer_cast_user_to_model)
27
+ type.nobrainer_cast_user_to_model(value)
28
+ else
29
+ raise NoBrainer::Error::InvalidType unless value.is_a?(type)
30
+ value
31
+ end
129
32
  rescue NoBrainer::Error::InvalidType => error
130
- error.type = field_def[:type]
33
+ error.type = type
131
34
  error.value = value
132
35
  error.attr_name = attr
133
36
  raise error
134
37
  end
135
38
 
136
- def inherited(subclass)
137
- super
138
- subclass.cast_db_to_user_fields = self.cast_db_to_user_fields.dup
39
+ def cast_model_to_db_for(attr, value)
40
+ type = fields[attr.to_sym].try(:[], :type)
41
+ return value if type.nil? || value.nil? || !type.respond_to?(:nobrainer_cast_model_to_db)
42
+ type.nobrainer_cast_model_to_db(value)
43
+ end
44
+
45
+ def cast_db_to_model_for(attr, value)
46
+ type = fields[attr.to_sym].try(:[], :type)
47
+ return value if type.nil? || value.nil? || !type.respond_to?(:nobrainer_cast_db_to_model)
48
+ type.nobrainer_cast_db_to_model(value)
49
+ end
50
+
51
+ def cast_user_to_db_for(attr, value)
52
+ value = cast_user_to_model_for(attr, value)
53
+ cast_model_to_db_for(attr, value)
54
+ end
55
+
56
+ def persistable_attributes(attrs)
57
+ Hash[attrs.map { |k,v| [k, cast_model_to_db_for(k, v)] }]
139
58
  end
140
59
 
141
60
  def _field(attr, options={})
142
61
  super
143
62
 
144
- if options[:cast_db_to_user]
145
- ([self] + descendants).each do |klass|
146
- klass.cast_db_to_user_fields << attr
147
- end
148
- end
63
+ NoBrainer::Document::Types.load_type_extensions(options[:type]) if options[:type]
149
64
 
150
65
  inject_in_layer :types do
151
66
  define_method("#{attr}=") do |value|
152
67
  begin
153
- value = self.class.cast_user_to_db_for(attr, value)
68
+ value = self.class.cast_user_to_model_for(attr, value)
154
69
  @pending_type_errors.try(:delete, attr)
155
70
  rescue NoBrainer::Error::InvalidType => error
156
71
  @pending_type_errors ||= {}
@@ -163,21 +78,38 @@ module NoBrainer::Document::Types
163
78
  end
164
79
  end
165
80
 
166
- def field(attr, options={})
167
- if options[:type]
168
- options = options.merge(
169
- :cast_user_to_db => NoBrainer::Document::Types::CastUserToDB.lookup(options[:type]),
170
- :cast_db_to_user => NoBrainer::Document::Types::CastDBToUser.lookup(options[:type]))
171
- end
172
- super
173
- end
174
-
175
81
  def _remove_field(attr, options={})
176
82
  super
83
+
177
84
  inject_in_layer :types do
178
85
  remove_method("#{attr}=")
179
86
  remove_method("#{attr}?") if method_defined?("#{attr}?")
180
87
  end
181
88
  end
89
+
90
+ def field(attr, options={})
91
+ if options[:type] == Array || options[:type] == Hash
92
+ # XXX For the moment, NoBrainer does not support these complex types
93
+ options.delete(:type)
94
+ end
95
+ super
96
+ end
97
+ end
98
+
99
+ require File.join(File.dirname(__FILE__), 'types', 'boolean')
100
+ Boolean = NoBrainer::Boolean
101
+
102
+ class << self
103
+ mattr_accessor :loaded_extensions
104
+ self.loaded_extensions = Set.new
105
+ def load_type_extensions(klass)
106
+ unless loaded_extensions.include?(klass)
107
+ begin
108
+ require File.join(File.dirname(__FILE__), 'types', klass.name.underscore)
109
+ rescue LoadError
110
+ end
111
+ loaded_extensions << klass
112
+ end
113
+ end
182
114
  end
183
115
  end
@@ -0,0 +1,26 @@
1
+ # We namespace our fake Boolean class to avoid polluting the global namespace
2
+ class NoBrainer::Boolean
3
+ def initialize; raise; end
4
+ def self.inspect; 'Boolean'; end
5
+ def self.to_s; inspect; end
6
+ def self.name; inspect; end
7
+
8
+ module NoBrainerExtentions
9
+ InvalidType = NoBrainer::Error::InvalidType
10
+
11
+ def nobrainer_cast_user_to_model(value)
12
+ case value
13
+ when TrueClass then true
14
+ when FalseClass then false
15
+ when String, Integer
16
+ value = value.to_s.strip.downcase
17
+ return true if value.in? %w(true yes t 1)
18
+ return false if value.in? %w(false no f 0)
19
+ raise InvalidType
20
+ else raise InvalidType
21
+ end
22
+ end
23
+ end
24
+ extend NoBrainerExtentions
25
+ end
26
+
@@ -0,0 +1,26 @@
1
+ class Date
2
+ module NoBrainerExtentions
3
+ InvalidType = NoBrainer::Error::InvalidType
4
+
5
+ def nobrainer_cast_user_to_model(value)
6
+ case value
7
+ when Date then value
8
+ when String
9
+ value = value.strip
10
+ date = Date.parse(value) rescue (raise InvalidType)
11
+ raise InvalidType unless date.iso8601 == value
12
+ date
13
+ else raise InvalidType
14
+ end
15
+ end
16
+
17
+ def nobrainer_cast_db_to_model(value)
18
+ value.is_a?(Time) ? value.to_date : value
19
+ end
20
+
21
+ def nobrainer_cast_model_to_db(value)
22
+ value.is_a?(Date) ? Time.utc(value.year, value.month, value.day) : value
23
+ end
24
+ end
25
+ extend NoBrainerExtentions
26
+ end
@@ -0,0 +1,20 @@
1
+ class Float
2
+ module NoBrainerExtentions
3
+ InvalidType = NoBrainer::Error::InvalidType
4
+
5
+ def nobrainer_cast_user_to_model(value)
6
+ case value
7
+ when Float then value
8
+ when Integer then value.to_f
9
+ when String
10
+ value = value.strip.gsub(/^\+/, '')
11
+ value = value.gsub(/0+$/, '') if value['.']
12
+ value = value.gsub(/\.$/, '')
13
+ value = "#{value}.0" unless value['.']
14
+ value.to_f.tap { |new_value| new_value.to_s == value or raise InvalidType }
15
+ else raise InvalidType
16
+ end
17
+ end
18
+ end
19
+ extend NoBrainerExtentions
20
+ end
@@ -0,0 +1,18 @@
1
+ class Integer
2
+ module NoBrainerExtentions
3
+ InvalidType = NoBrainer::Error::InvalidType
4
+
5
+ def nobrainer_cast_user_to_model(value)
6
+ case value
7
+ when Integer then value
8
+ when String
9
+ value = value.strip.gsub(/^\+/, '')
10
+ value.to_i.tap { |new_value| new_value.to_s == value or raise InvalidType }
11
+ when Float
12
+ value.to_i.tap { |new_value| new_value.to_f == value or raise InvalidType }
13
+ else raise InvalidType
14
+ end
15
+ end
16
+ end
17
+ extend NoBrainerExtentions
18
+ end
@@ -0,0 +1,14 @@
1
+ class String
2
+ module NoBrainerExtentions
3
+ InvalidType = NoBrainer::Error::InvalidType
4
+
5
+ def nobrainer_cast_user_to_model(value)
6
+ case value
7
+ when String then value
8
+ when Symbol then value.to_s
9
+ else raise InvalidType
10
+ end
11
+ end
12
+ end
13
+ extend NoBrainerExtentions
14
+ end
@@ -0,0 +1,21 @@
1
+ class Symbol
2
+ module NoBrainerExtentions
3
+ InvalidType = NoBrainer::Error::InvalidType
4
+
5
+ def nobrainer_cast_user_to_model(value)
6
+ case value
7
+ when Symbol then value
8
+ when String
9
+ value = value.strip
10
+ raise InvalidType if value.empty?
11
+ value.to_sym
12
+ else raise InvalidType
13
+ end
14
+ end
15
+
16
+ def nobrainer_cast_db_to_model(value)
17
+ value.to_sym rescue (value.to_s.to_sym rescue value)
18
+ end
19
+ end
20
+ extend NoBrainerExtentions
21
+ end
@@ -0,0 +1,41 @@
1
+ require 'time'
2
+
3
+ class Time
4
+ module NoBrainerExtentions
5
+ InvalidType = NoBrainer::Error::InvalidType
6
+
7
+ def nobrainer_cast_user_to_model(value)
8
+ case value
9
+ when Time then time = value
10
+ when String
11
+ value = value.strip.sub(/Z$/, '+00:00')
12
+ # Using DateTime to preserve the timezone offset
13
+ dt = DateTime.parse(value) rescue (raise InvalidType)
14
+ time = Time.new(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.zone)
15
+ raise InvalidType unless time.iso8601 == value
16
+ else raise InvalidType
17
+ end
18
+
19
+ nobrainer_timezoned(NoBrainer::Config.user_timezone, time)
20
+ end
21
+
22
+ def nobrainer_cast_db_to_model(value)
23
+ return value unless value.is_a?(Time)
24
+ nobrainer_timezoned(NoBrainer::Config.user_timezone, value)
25
+ end
26
+
27
+ def nobrainer_cast_model_to_db(value)
28
+ return value unless value.is_a?(Time)
29
+ nobrainer_timezoned(NoBrainer::Config.db_timezone, value)
30
+ end
31
+
32
+ def nobrainer_timezoned(tz, value)
33
+ case tz
34
+ when :local then value.getlocal
35
+ when :utc then value.getutc
36
+ when :unchanged then value
37
+ end
38
+ end
39
+ end
40
+ extend NoBrainerExtentions
41
+ end
@@ -18,6 +18,7 @@ module NoBrainer::Document::Validation
18
18
  super
19
19
  validates(attr, { :presence => options[:required] }) if options.has_key?(:required)
20
20
  validates(attr, { :uniqueness => options[:unique] }) if options.has_key?(:unique)
21
+ validates(attr, { :inclusion => {:in => options[:in]} }) if options.has_key?(:in)
21
22
  validates(attr, options[:validates]) if options[:validates]
22
23
  end
23
24
  end
@@ -33,7 +33,7 @@ module NoBrainer::Error
33
33
  end
34
34
 
35
35
  def message
36
- "#{attr_name} should be used with a #{human_type_name}. Got `#{value}`"
36
+ "#{attr_name} should be used with a #{human_type_name}. Got `#{value}` (#{value.class})"
37
37
  end
38
38
  end
39
39
  end
data/lib/nobrainer.rb CHANGED
@@ -45,6 +45,10 @@ module NoBrainer
45
45
  def jruby?
46
46
  RUBY_PLATFORM == 'java'
47
47
  end
48
+
49
+ def user_caller
50
+ caller.reject { |s| s =~ /\/no_brainer\// }.first
51
+ end
48
52
  end
49
53
 
50
54
  DecoratedSymbol.hook
@@ -2,7 +2,8 @@ require "rails/generators/nobrainer"
2
2
 
3
3
  module NoBrainer::Generators
4
4
  class ModelGenerator < Base
5
- argument :attributes, :type => :array, default: [], banner: "field ... field"
5
+ argument(:attributes, :type => :array, default: [],
6
+ banner: "field[:type][:index] ... field[:type][:index]")
6
7
 
7
8
  check_class_collision
8
9
 
@@ -2,12 +2,17 @@
2
2
  class <%= class_name %><%= " < #{options[:parent].classify}" if options[:parent] %>
3
3
  <% unless options[:parent] -%>
4
4
  include NoBrainer::Document
5
+ include NoBrainer::Document::Timestamps
6
+
5
7
  <% end -%>
6
8
  <% attributes.reject(&:reference?).each do |attribute| -%>
7
- field :<%= attribute.name %>
9
+ field :<%= attribute.name -%>
10
+ <%= puts attribute; ", :type => #{attribute.type.to_s.classify}" if attribute.type != :object -%>
11
+ <%= ", :index => true" if attribute.has_index? %>
8
12
  <% end -%>
9
13
  <% attributes.select(&:reference?).each do |attribute| -%>
10
- belongs_to :<%= attribute.name %>
14
+ belongs_to :<%= attribute.name -%>
15
+ <%= ", :index => true" if attribute.has_index? %>
11
16
  <% end -%>
12
17
  end
13
18
  <% end -%>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nobrainer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicolas Viennot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-17 00:00:00.000000000 Z
11
+ date: 2014-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rethinkdb
@@ -119,6 +119,13 @@ files:
119
119
  - lib/no_brainer/document/store_in.rb
120
120
  - lib/no_brainer/document/timestamps.rb
121
121
  - lib/no_brainer/document/types.rb
122
+ - lib/no_brainer/document/types/boolean.rb
123
+ - lib/no_brainer/document/types/date.rb
124
+ - lib/no_brainer/document/types/float.rb
125
+ - lib/no_brainer/document/types/integer.rb
126
+ - lib/no_brainer/document/types/string.rb
127
+ - lib/no_brainer/document/types/symbol.rb
128
+ - lib/no_brainer/document/types/time.rb
122
129
  - lib/no_brainer/document/uniqueness.rb
123
130
  - lib/no_brainer/document/validation.rb
124
131
  - lib/no_brainer/error.rb