sequel 4.13.0 → 4.14.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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +24 -0
  3. data/doc/active_record.rdoc +4 -4
  4. data/doc/advanced_associations.rdoc +2 -2
  5. data/doc/association_basics.rdoc +11 -11
  6. data/doc/cheat_sheet.rdoc +7 -7
  7. data/doc/core_extensions.rdoc +1 -1
  8. data/doc/dataset_filtering.rdoc +1 -1
  9. data/doc/extensions.rdoc +1 -1
  10. data/doc/migration.rdoc +3 -3
  11. data/doc/model_hooks.rdoc +1 -1
  12. data/doc/opening_databases.rdoc +4 -0
  13. data/doc/postgresql.rdoc +2 -2
  14. data/doc/prepared_statements.rdoc +1 -1
  15. data/doc/querying.rdoc +31 -31
  16. data/doc/release_notes/4.13.0.txt +1 -1
  17. data/doc/release_notes/4.14.0.txt +68 -0
  18. data/doc/schema_modification.rdoc +1 -1
  19. data/doc/sharding.rdoc +2 -2
  20. data/doc/sql.rdoc +1 -1
  21. data/doc/virtual_rows.rdoc +2 -2
  22. data/lib/sequel/adapters/jdbc/jtds.rb +4 -0
  23. data/lib/sequel/adapters/mysql.rb +18 -18
  24. data/lib/sequel/adapters/mysql2.rb +7 -7
  25. data/lib/sequel/adapters/shared/mysql.rb +15 -5
  26. data/lib/sequel/adapters/shared/postgres.rb +71 -58
  27. data/lib/sequel/adapters/shared/sqlite.rb +2 -2
  28. data/lib/sequel/ast_transformer.rb +1 -1
  29. data/lib/sequel/connection_pool/sharded_single.rb +8 -8
  30. data/lib/sequel/connection_pool/sharded_threaded.rb +8 -8
  31. data/lib/sequel/database/connecting.rb +1 -1
  32. data/lib/sequel/database/schema_generator.rb +12 -0
  33. data/lib/sequel/database/schema_methods.rb +8 -7
  34. data/lib/sequel/database/transactions.rb +1 -2
  35. data/lib/sequel/dataset/actions.rb +4 -4
  36. data/lib/sequel/dataset/graph.rb +4 -0
  37. data/lib/sequel/dataset/query.rb +18 -18
  38. data/lib/sequel/dataset/sql.rb +3 -3
  39. data/lib/sequel/extensions/_pretty_table.rb +1 -0
  40. data/lib/sequel/extensions/arbitrary_servers.rb +3 -2
  41. data/lib/sequel/extensions/columns_introspection.rb +1 -0
  42. data/lib/sequel/extensions/connection_validator.rb +1 -0
  43. data/lib/sequel/extensions/constraint_validations.rb +1 -0
  44. data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -0
  45. data/lib/sequel/extensions/dataset_source_alias.rb +1 -0
  46. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  47. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +1 -0
  48. data/lib/sequel/extensions/error_sql.rb +1 -0
  49. data/lib/sequel/extensions/eval_inspect.rb +1 -0
  50. data/lib/sequel/extensions/filter_having.rb +1 -0
  51. data/lib/sequel/extensions/from_block.rb +1 -0
  52. data/lib/sequel/extensions/graph_each.rb +1 -0
  53. data/lib/sequel/extensions/hash_aliases.rb +1 -0
  54. data/lib/sequel/extensions/looser_typecasting.rb +1 -0
  55. data/lib/sequel/extensions/meta_def.rb +1 -0
  56. data/lib/sequel/extensions/migration.rb +1 -0
  57. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +1 -0
  58. data/lib/sequel/extensions/named_timezones.rb +1 -0
  59. data/lib/sequel/extensions/null_dataset.rb +1 -0
  60. data/lib/sequel/extensions/pagination.rb +1 -0
  61. data/lib/sequel/extensions/pg_array.rb +2 -2
  62. data/lib/sequel/extensions/pg_array_ops.rb +1 -0
  63. data/lib/sequel/extensions/pg_enum.rb +1 -0
  64. data/lib/sequel/extensions/pg_hstore_ops.rb +1 -0
  65. data/lib/sequel/extensions/pg_json_ops.rb +1 -0
  66. data/lib/sequel/extensions/pg_loose_count.rb +1 -0
  67. data/lib/sequel/extensions/pg_range_ops.rb +1 -0
  68. data/lib/sequel/extensions/pg_row_ops.rb +1 -0
  69. data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -0
  70. data/lib/sequel/extensions/pretty_table.rb +1 -0
  71. data/lib/sequel/extensions/query.rb +1 -0
  72. data/lib/sequel/extensions/query_literals.rb +1 -0
  73. data/lib/sequel/extensions/schema_caching.rb +1 -0
  74. data/lib/sequel/extensions/schema_dumper.rb +1 -1
  75. data/lib/sequel/extensions/select_remove.rb +1 -0
  76. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +1 -0
  77. data/lib/sequel/extensions/server_block.rb +1 -0
  78. data/lib/sequel/extensions/set_overrides.rb +1 -0
  79. data/lib/sequel/extensions/split_array_nil.rb +1 -0
  80. data/lib/sequel/extensions/thread_local_timezones.rb +1 -0
  81. data/lib/sequel/extensions/to_dot.rb +1 -0
  82. data/lib/sequel/model/associations.rb +5 -5
  83. data/lib/sequel/model/base.rb +3 -3
  84. data/lib/sequel/plugins/association_proxies.rb +1 -1
  85. data/lib/sequel/plugins/caching.rb +8 -3
  86. data/lib/sequel/plugins/class_table_inheritance.rb +20 -11
  87. data/lib/sequel/plugins/composition.rb +18 -18
  88. data/lib/sequel/plugins/json_serializer.rb +3 -3
  89. data/lib/sequel/plugins/lazy_attributes.rb +23 -9
  90. data/lib/sequel/plugins/many_through_many.rb +21 -21
  91. data/lib/sequel/plugins/nested_attributes.rb +7 -3
  92. data/lib/sequel/plugins/pg_row.rb +1 -1
  93. data/lib/sequel/plugins/rcte_tree.rb +13 -13
  94. data/lib/sequel/plugins/sharding.rb +6 -6
  95. data/lib/sequel/plugins/timestamps.rb +4 -4
  96. data/lib/sequel/plugins/touch.rb +7 -7
  97. data/lib/sequel/plugins/tree.rb +1 -1
  98. data/lib/sequel/plugins/validation_class_methods.rb +36 -36
  99. data/lib/sequel/plugins/validation_helpers.rb +3 -4
  100. data/lib/sequel/plugins/xml_serializer.rb +29 -29
  101. data/lib/sequel/sql.rb +22 -11
  102. data/lib/sequel/version.rb +1 -1
  103. data/spec/adapters/postgres_spec.rb +10 -0
  104. data/spec/core/database_spec.rb +3 -4
  105. data/spec/core/dataset_spec.rb +16 -1
  106. data/spec/core/expression_filters_spec.rb +12 -0
  107. data/spec/core/object_graph_spec.rb +5 -0
  108. data/spec/core/placeholder_literalizer_spec.rb +8 -0
  109. data/spec/extensions/caching_spec.rb +18 -0
  110. data/spec/extensions/class_table_inheritance_spec.rb +34 -0
  111. data/spec/extensions/many_through_many_spec.rb +4 -0
  112. data/spec/extensions/nested_attributes_spec.rb +59 -4
  113. data/spec/extensions/pg_array_associations_spec.rb +5 -0
  114. data/spec/extensions/single_table_inheritance_spec.rb +23 -1
  115. data/spec/integration/plugin_test.rb +17 -0
  116. data/spec/model/eager_loading_spec.rb +8 -0
  117. metadata +4 -2
@@ -18,17 +18,17 @@ module Sequel
18
18
  # album.to_json(:only=>:name)
19
19
  # album.to_json(:except=>[:id, :artist_id])
20
20
  # # => '{"json_class"="Album","name"=>"RF"}'
21
- #
21
+ #
22
22
  # album.to_json(:include=>:artist)
23
23
  # # => '{"json_class":"Album","id":1,"name":"RF","artist_id":2,
24
- # "artist":{"json_class":"Artist","id":2,"name":"YJM"}}'
24
+ # # "artist":{"json_class":"Artist","id":2,"name":"YJM"}}'
25
25
  #
26
26
  # You can use a hash value with <tt>:include</tt> to pass options
27
27
  # to associations:
28
28
  #
29
29
  # album.to_json(:include=>{:artist=>{:only=>:name}})
30
30
  # # => '{"json_class":"Album","id":1,"name":"RF","artist_id":2,
31
- # "artist":{"json_class":"Artist","name":"YJM"}}'
31
+ # # "artist":{"json_class":"Artist","name":"YJM"}}'
32
32
  #
33
33
  # You can specify the <tt>:root</tt> option to nest the JSON under the
34
34
  # name of the model:
@@ -53,13 +53,15 @@ module Sequel
53
53
 
54
54
  private
55
55
 
56
- # Add a lazy attribute getter method to the lazy_attributes_module
57
- def define_lazy_attribute_getter(a)
56
+ # Add a lazy attribute getter method to the lazy_attributes_module. Options:
57
+ # :dataset :: The base dataset to use for the lazy attribute lookup
58
+ # :table :: The table name to use to qualify the attribute and primary key columns.
59
+ def define_lazy_attribute_getter(a, opts=OPTS)
58
60
  include(self.lazy_attributes_module ||= Module.new) unless lazy_attributes_module
59
61
  lazy_attributes_module.class_eval do
60
62
  define_method(a) do
61
63
  if !values.has_key?(a) && !new?
62
- lazy_attribute_lookup(a)
64
+ lazy_attribute_lookup(a, opts)
63
65
  else
64
66
  super()
65
67
  end
@@ -75,10 +77,22 @@ module Sequel
75
77
  # attribute for all of those objects. If not, query the database for
76
78
  # the attribute for just the current object. Return the value of
77
79
  # the attribute for the current object.
78
- def lazy_attribute_lookup(a)
79
- selection = Sequel.qualify(model.table_name, a)
80
+ def lazy_attribute_lookup(a, opts=OPTS)
81
+ unless table = opts[:table]
82
+ table = model.table_name
83
+ end
84
+
85
+ if base_ds = opts[:dataset]
86
+ ds = base_ds.where(model.qualified_primary_key_hash(pk, table))
87
+ else
88
+ base_ds = model.dataset
89
+ ds = this
90
+ end
91
+
92
+ selection = Sequel.qualify(table, a)
93
+
80
94
  if frozen?
81
- return this.dup.get(selection)
95
+ return ds.dup.get(selection)
82
96
  end
83
97
 
84
98
  if retrieved_with
@@ -86,15 +100,15 @@ module Sequel
86
100
  composite_pk = true if primary_key.is_a?(Array)
87
101
  id_map = {}
88
102
  retrieved_with.each{|o| id_map[o.pk] = o unless o.values.has_key?(a) || o.frozen?}
89
- predicate_key = composite_pk ? primary_key.map{|k| Sequel.qualify(model.table_name, k)} : Sequel.qualify(model.table_name, primary_key)
90
- model.select(*(Array(primary_key).map{|k| Sequel.qualify(model.table_name, k)} + [selection])).where(predicate_key=>id_map.keys).naked.each do |row|
103
+ predicate_key = composite_pk ? primary_key.map{|k| Sequel.qualify(table, k)} : Sequel.qualify(table, primary_key)
104
+ base_ds.select(*(Array(primary_key).map{|k| Sequel.qualify(table, k)} + [selection])).where(predicate_key=>id_map.keys).naked.each do |row|
91
105
  obj = id_map[composite_pk ? row.values_at(*primary_key) : row[primary_key]]
92
106
  if obj && !obj.values.has_key?(a)
93
107
  obj.values[a] = row[a]
94
108
  end
95
109
  end
96
110
  end
97
- values[a] = this.get(selection) unless values.has_key?(a)
111
+ values[a] = ds.get(selection) unless values.has_key?(a)
98
112
  values[a]
99
113
  end
100
114
  end
@@ -20,9 +20,9 @@ module Sequel
20
20
  #
21
21
  # This argument is an array of arrays with three elements. Each entry in the main array represents a JOIN in SQL:
22
22
  #
23
- # * The first element in each array represents the name of the table to join.
24
- # * The second element in each array represents the column used to join to the previous table.
25
- # * The third element in each array represents the column used to join to the next table.
23
+ # first element :: represents the name of the table to join.
24
+ # second element :: represents the column used to join to the previous table.
25
+ # third element :: represents the column used to join to the next table.
26
26
  #
27
27
  # So the "Artist.many_through_many :tags" is translated into something similar to:
28
28
  #
@@ -180,21 +180,21 @@ module Sequel
180
180
 
181
181
  module ClassMethods
182
182
  # Create a many_through_many association. Arguments:
183
- # * name - Same as associate, the name of the association.
184
- # * through - The tables and keys to join between the current table and the associated table.
185
- # Must be an array, with elements that are either 3 element arrays, or hashes with keys :table, :left, and :right.
186
- # The required entries in the array/hash are:
187
- # :table (first array element) :: The name of the table to join.
188
- # :left (middle array element) :: The key joining the table to the previous table. Can use an
189
- # array of symbols for a composite key association.
190
- # :right (last array element) :: The key joining the table to the next table. Can use an
191
- # array of symbols for a composite key association.
192
- # If a hash is provided, the following keys are respected when using eager_graph:
193
- # :block :: A proc to use as the block argument to join.
194
- # :conditions :: Extra conditions to add to the JOIN ON clause. Must be a hash or array of two pairs.
195
- # :join_type :: The join type to use for the join, defaults to :left_outer.
196
- # :only_conditions :: Conditions to use for the join instead of the ones specified by the keys.
197
- # * opts - The options for the associaion. Takes the same options as many_to_many.
183
+ # name :: Same as associate, the name of the association.
184
+ # through :: The tables and keys to join between the current table and the associated table.
185
+ # Must be an array, with elements that are either 3 element arrays, or hashes with keys :table, :left, and :right.
186
+ # The required entries in the array/hash are:
187
+ # :table (first array element) :: The name of the table to join.
188
+ # :left (middle array element) :: The key joining the table to the previous table. Can use an
189
+ # array of symbols for a composite key association.
190
+ # :right (last array element) :: The key joining the table to the next table. Can use an
191
+ # array of symbols for a composite key association.
192
+ # If a hash is provided, the following keys are respected when using eager_graph:
193
+ # :block :: A proc to use as the block argument to join.
194
+ # :conditions :: Extra conditions to add to the JOIN ON clause. Must be a hash or array of two pairs.
195
+ # :join_type :: The join type to use for the join, defaults to :left_outer.
196
+ # :only_conditions :: Conditions to use for the join instead of the ones specified by the keys.
197
+ # opts :: The options for the associaion. Takes the same options as many_to_many.
198
198
  def many_through_many(name, through, opts=OPTS, &block)
199
199
  associate(:many_through_many, name, opts.merge(through.is_a?(Hash) ? through : {:through=>through}), &block)
200
200
  end
@@ -257,14 +257,14 @@ module Sequel
257
257
  select_all(egds.first_source).
258
258
  select_append(*associated_key_array)
259
259
  egds = opts.apply_eager_graph_limit_strategy(egls, egds)
260
- ds.graph(egds, associated_key_array.map{|v| v.alias}.zip(Array(lpkcs)) + conditions, :qualify=>:deep, :table_alias=>eo[:table_alias], :implicit_qualifier=>iq, :join_type=>eo[:join_type]||join_type, :from_self_alias=>eo[:from_self_alias], :select=>select||orig_egds.columns, &graph_block)
260
+ ds.graph(egds, associated_key_array.map{|v| v.alias}.zip(Array(lpkcs)) + conditions, :qualify=>:deep, :table_alias=>eo[:table_alias], :implicit_qualifier=>iq, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], :from_self_alias=>eo[:from_self_alias], :select=>select||orig_egds.columns, &graph_block)
261
261
  else
262
262
  opts.edges.each do |t|
263
- ds = ds.graph(t[:table], t.fetch(:only_conditions, (Array(t[:right]).zip(Array(t[:left])) + t[:conditions])), :select=>false, :table_alias=>ds.unused_table_alias(t[:table]), :join_type=>eo[:join_type]||t[:join_type], :qualify=>:deep, :implicit_qualifier=>iq, :from_self_alias=>eo[:from_self_alias], &t[:block])
263
+ ds = ds.graph(t[:table], t.fetch(:only_conditions, (Array(t[:right]).zip(Array(t[:left])) + t[:conditions])), :select=>false, :table_alias=>ds.unused_table_alias(t[:table]), :join_type=>eo[:join_type]||t[:join_type], :join_only=>eo[:join_only], :qualify=>:deep, :implicit_qualifier=>iq, :from_self_alias=>eo[:from_self_alias], &t[:block])
264
264
  iq = nil
265
265
  end
266
266
  fe = opts.final_edge
267
- ds.graph(opts.associated_class, use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, &graph_block)
267
+ ds.graph(opts.associated_class, use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
268
268
  end
269
269
  end
270
270
  end
@@ -62,7 +62,7 @@ module Sequel
62
62
  #
63
63
  # Your web stack will probably parse that into a nested hash similar to:
64
64
  #
65
- # {:artist=>{:name=>?, :albums_attributes=>{0=>{:name=>?}, 1=>{:id=>?, :name=>?}}}}
65
+ # {:artist=>{:name=>'Y', :albums_attributes=>{0=>{:name=>'X'}, 1=>{:id=>'2', :name=>'Z'}}}}
66
66
  #
67
67
  # Then you can do:
68
68
  #
@@ -218,6 +218,9 @@ module Sequel
218
218
  end
219
219
  end
220
220
  after_save_hook{obj.destroy} if opts[:destroy]
221
+ if reflection.returns_array?
222
+ associations[reflection[:name]].delete(obj)
223
+ end
221
224
  obj
222
225
  end
223
226
 
@@ -304,8 +307,9 @@ module Sequel
304
307
  # which will fail if we validate before saving the current object. If there is
305
308
  # no value for the foreign key, set it to the current primary key value, or a dummy
306
309
  # value of 0 if we haven't saved the current object.
307
- obj.values[key] = pk || 0
308
- key = nil if pk
310
+ p_key = pk unless pk.is_a?(Array)
311
+ obj.values[key] = p_key || 0
312
+ key = nil if p_key
309
313
  end
310
314
  obj.errors.full_messages.each{|m| errors.add(association, m)} unless obj.valid?
311
315
  if key && !pk_val
@@ -28,7 +28,7 @@ module Sequel
28
28
  #
29
29
  # DB[:company].first
30
30
  # # => {:name=>'MS', :address=>
31
- # Address.load(:street=>'123 Foo St', :city=>'Bar Town', :zip=>'12345')}
31
+ # # Address.load(:street=>'123 Foo St', :city=>'Bar Town', :zip=>'12345')}
32
32
  #
33
33
  # If you want a lot of your models to be used as row types, you can load the
34
34
  # plugin into Sequel::Model itself:
@@ -66,10 +66,10 @@ module Sequel
66
66
  # You can override the options for any specific association by making
67
67
  # sure the plugin options contain one of the following keys:
68
68
  #
69
- # * :parent - hash of options for the parent association
70
- # * :children - hash of options for the children association
71
- # * :ancestors - hash of options for the ancestors association
72
- # * :descendants - hash of options for the descendants association
69
+ # :parent :: hash of options for the parent association
70
+ # :children :: hash of options for the children association
71
+ # :ancestors :: hash of options for the ancestors association
72
+ # :descendants :: hash of options for the descendants association
73
73
  #
74
74
  # Note that you can change the name of the above associations by specifying
75
75
  # a :name key in the appropriate hash of options above. For example:
@@ -80,15 +80,15 @@ module Sequel
80
80
  # Any other keys in the main options hash are treated as options shared by
81
81
  # all of the associations. Here's a few options that affect the plugin:
82
82
  #
83
- # * :key - The foreign key in the table that points to the primary key
84
- # of the parent (default: :parent_id)
85
- # * :primary_key - The primary key to use (default: the model's primary key)
86
- # * :key_alias - The symbol identifier to use for aliasing when eager
87
- # loading (default: :x_root_x)
88
- # * :cte_name - The symbol identifier to use for the common table expression
89
- # (default: :t)
90
- # * :level_alias - The symbol identifier to use when eagerly loading descendants
91
- # up to a given level (default: :x_level_x)
83
+ # :key :: The foreign key in the table that points to the primary key
84
+ # of the parent (default: :parent_id)
85
+ # :primary_key :: The primary key to use (default: the model's primary key)
86
+ # :key_alias :: The symbol identifier to use for aliasing when eager
87
+ # loading (default: :x_root_x)
88
+ # :cte_name :: The symbol identifier to use for the common table expression
89
+ # (default: :t)
90
+ # :level_alias :: The symbol identifier to use when eagerly loading descendants
91
+ # up to a given level (default: :x_level_x)
92
92
  module RcteTree
93
93
  # Create the appropriate parent, children, ancestors, and descendants
94
94
  # associations for the model.
@@ -3,12 +3,12 @@ module Sequel
3
3
  # The sharding plugin augments Sequel's default model sharding support
4
4
  # in the following ways:
5
5
  #
6
- # 1) It automatically sets model instances to be saved back to the
7
- # shard they were retreived from.
8
- # 2) It makes model associations use the same shard as the model
9
- # object.
10
- # 3) It adds a slightly nicer API for creating model instances on
11
- # specific shards.
6
+ # * It automatically sets model instances to be saved back to the
7
+ # shard they were retreived from.
8
+ # * It makes model associations use the same shard as the model
9
+ # object.
10
+ # * It adds a slightly nicer API for creating model instances on
11
+ # specific shards.
12
12
  #
13
13
  # Usage:
14
14
  #
@@ -22,10 +22,10 @@ module Sequel
22
22
  # Configure the plugin by setting the available options. Note that
23
23
  # if this method is run more than once, previous settings are ignored,
24
24
  # and it will just use the settings given or the default settings. Options:
25
- # * :create - The field to hold the create timestamp (default: :created_at)
26
- # * :force - Whether to overwrite an existing create timestamp (default: false)
27
- # * :update - The field to hold the update timestamp (default: :updated_at)
28
- # * :update_on_create - Whether to set the update timestamp to the create timestamp when creating (default: false)
25
+ # :create :: The field to hold the create timestamp (default: :created_at)
26
+ # :force :: Whether to overwrite an existing create timestamp (default: false)
27
+ # :update :: The field to hold the update timestamp (default: :updated_at)
28
+ # :update_on_create :: Whether to set the update timestamp to the create timestamp when creating (default: false)
29
29
  def self.configure(model, opts=OPTS)
30
30
  model.instance_eval do
31
31
  @create_timestamp_field = opts[:create]||:created_at
@@ -36,13 +36,13 @@ module Sequel
36
36
 
37
37
  # Set the touch_column and touched_associations variables for the model.
38
38
  # Options:
39
- # * :associations - The associations to touch when a model instance is
40
- # updated or destroyed. Can be a symbol for a single association,
41
- # a hash with association keys and column values, or an array of
42
- # symbols and/or hashes. If a symbol is used, the column used
43
- # when updating the associated objects is the model's touch_column.
44
- # If a hash is used, the value is used as the column to update.
45
- # * :column - The column to modify when touching a model instance.
39
+ # :associations :: The associations to touch when a model instance is
40
+ # updated or destroyed. Can be a symbol for a single association,
41
+ # a hash with association keys and column values, or an array of
42
+ # symbols and/or hashes. If a symbol is used, the column used
43
+ # when updating the associated objects is the model's touch_column.
44
+ # If a hash is used, the value is used as the column to update.
45
+ # :column :: The column to modify when touching a model instance.
46
46
  def self.configure(model, opts=OPTS)
47
47
  model.touch_column = opts[:column] || TOUCH_COLUMN_DEFAULT if opts[:column] || !model.touch_column
48
48
  model.touch_associations(opts[:associations]) if opts[:associations]
@@ -70,7 +70,7 @@ module Sequel
70
70
 
71
71
  # Returns the dataset for retrieval of all root nodes
72
72
  #
73
- # TreeClass.roots_dataset => Sequel#Dataset
73
+ # TreeClass.roots_dataset # => Sequel::Dataset instance
74
74
  def roots_dataset
75
75
  ds = where(Sequel.or(Array(parent_column).zip([])))
76
76
  ds = ds.order(*tree_order) if tree_order
@@ -116,8 +116,8 @@ module Sequel
116
116
  # :allow_nil is assumed to be true instead of false.
117
117
  #
118
118
  # Possible Options:
119
- # * :accept - The value required for the object to be valid (default: '1')
120
- # * :message - The message to use (default: 'is not accepted')
119
+ # :accept :: The value required for the object to be valid (default: '1')
120
+ # :message :: The message to use (default: 'is not accepted')
121
121
  def validates_acceptance_of(*atts)
122
122
  opts = {
123
123
  :message => 'is not accepted',
@@ -141,7 +141,7 @@ module Sequel
141
141
  # or email addresses on web forms.
142
142
  #
143
143
  # Possible Options:
144
- # * :message - The message to use (default: 'is not confirmed')
144
+ # :message :: The message to use (default: 'is not confirmed')
145
145
  def validates_confirmation_of(*atts)
146
146
  opts = {
147
147
  :message => 'is not confirmed',
@@ -163,20 +163,20 @@ module Sequel
163
163
  # end
164
164
  #
165
165
  # Possible Options:
166
- # * :allow_blank - Whether to skip the validation if the value is blank.
167
- # * :allow_missing - Whether to skip the validation if the attribute isn't a key in the
168
- # values hash. This is different from allow_nil, because Sequel only sends the attributes
169
- # in the values when doing an insert or update. If the attribute is not present, Sequel
170
- # doesn't specify it, so the database will use the table's default value. This is different
171
- # from having an attribute in values with a value of nil, which Sequel will send as NULL.
172
- # If your database table has a non NULL default, this may be a good option to use. You
173
- # don't want to use allow_nil, because if the attribute is in values but has a value nil,
174
- # Sequel will attempt to insert a NULL value into the database, instead of using the
175
- # database's default.
176
- # * :allow_nil - Whether to skip the validation if the value is nil.
177
- # * :if - A symbol (indicating an instance_method) or proc (which is instance_evaled)
178
- # skipping this validation if it returns nil or false.
179
- # * :tag - The tag to use for this validation.
166
+ # :allow_blank :: Whether to skip the validation if the value is blank.
167
+ # :allow_missing :: Whether to skip the validation if the attribute isn't a key in the
168
+ # values hash. This is different from allow_nil, because Sequel only sends the attributes
169
+ # in the values when doing an insert or update. If the attribute is not present, Sequel
170
+ # doesn't specify it, so the database will use the table's default value. This is different
171
+ # from having an attribute in values with a value of nil, which Sequel will send as NULL.
172
+ # If your database table has a non NULL default, this may be a good option to use. You
173
+ # don't want to use allow_nil, because if the attribute is in values but has a value nil,
174
+ # Sequel will attempt to insert a NULL value into the database, instead of using the
175
+ # database's default.
176
+ # :allow_nil :: Whether to skip the validation if the value is nil.
177
+ # :if :: A symbol (indicating an instance_method) or proc (which is instance_evaled)
178
+ # skipping this validation if it returns nil or false.
179
+ # :tag :: The tag to use for this validation.
180
180
  def validates_each(*atts, &block)
181
181
  opts = extract_options!(atts)
182
182
  blk = if (i = opts[:if]) || (am = opts[:allow_missing]) || (an = opts[:allow_nil]) || (ab = opts[:allow_blank])
@@ -205,8 +205,8 @@ module Sequel
205
205
  # value against the regular expression provided by the :with option.
206
206
  #
207
207
  # Possible Options:
208
- # * :message - The message to use (default: 'is invalid')
209
- # * :with - The regular expression to validate the value with (required).
208
+ # :message :: The message to use (default: 'is invalid')
209
+ # :with :: The regular expression to validate the value with (required).
210
210
  def validates_format_of(*atts)
211
211
  opts = {
212
212
  :message => 'is invalid',
@@ -227,16 +227,16 @@ module Sequel
227
227
  # Validates the length of an attribute.
228
228
  #
229
229
  # Possible Options:
230
- # * :is - The exact size required for the value to be valid (no default)
231
- # * :maximum - The maximum size allowed for the value (no default)
232
- # * :message - The message to use (no default, overrides :nil_message, :too_long, :too_short, and :wrong_length
233
- # options if present)
234
- # * :minimum - The minimum size allowed for the value (no default)
235
- # * :nil_message - The message to use use if :maximum option is used and the value is nil (default: 'is not present')
236
- # * :too_long - The message to use use if it the value is too long (default: 'is too long')
237
- # * :too_short - The message to use use if it the value is too short (default: 'is too short')
238
- # * :within - The array/range that must include the size of the value for it to be valid (no default)
239
- # * :wrong_length - The message to use use if it the value is not valid (default: 'is the wrong length')
230
+ # :is :: The exact size required for the value to be valid (no default)
231
+ # :maximum :: The maximum size allowed for the value (no default)
232
+ # :message :: The message to use (no default, overrides :nil_message, :too_long, :too_short, and :wrong_length
233
+ # options if present)
234
+ # :minimum :: The minimum size allowed for the value (no default)
235
+ # :nil_message :: The message to use use if :maximum option is used and the value is nil (default: 'is not present')
236
+ # :too_long :: The message to use use if it the value is too long (default: 'is too long')
237
+ # :too_short :: The message to use use if it the value is too short (default: 'is too short')
238
+ # :within :: The array/range that must include the size of the value for it to be valid (no default)
239
+ # :wrong_length :: The message to use use if it the value is not valid (default: 'is the wrong length')
240
240
  def validates_length_of(*atts)
241
241
  opts = {
242
242
  :nil_message => 'is not present',
@@ -267,8 +267,8 @@ module Sequel
267
267
  # Validates whether an attribute is a number.
268
268
  #
269
269
  # Possible Options:
270
- # * :message - The message to use (default: 'is not a number')
271
- # * :only_integer - Whether only integers are valid values (default: false)
270
+ # :message :: The message to use (default: 'is not a number')
271
+ # :only_integer :: Whether only integers are valid values (default: false)
272
272
  def validates_numericality_of(*atts)
273
273
  opts = {
274
274
  :message => 'is not a number',
@@ -293,7 +293,7 @@ module Sequel
293
293
  # with false considered present instead of absent.
294
294
  #
295
295
  # Possible Options:
296
- # * :message - The message to use (default: 'is not present')
296
+ # :message :: The message to use (default: 'is not present')
297
297
  def validates_presence_of(*atts)
298
298
  opts = {
299
299
  :message => 'is not present',
@@ -309,8 +309,8 @@ module Sequel
309
309
  # Validates that an attribute is within a specified range or set of values.
310
310
  #
311
311
  # Possible Options:
312
- # * :in - An array or range of values to check for validity (required)
313
- # * :message - The message to use (default: 'is not in range or set: <specified range>')
312
+ # :in :: An array or range of values to check for validity (required)
313
+ # :message :: The message to use (default: 'is not in range or set: <specified range>')
314
314
  def validates_inclusion_of(*atts)
315
315
  opts = extract_options!(atts)
316
316
  n = opts[:in]
@@ -331,7 +331,7 @@ module Sequel
331
331
  # time instead of at setter time.
332
332
  #
333
333
  # Possible Options:
334
- # * :message - The message to use (default: 'is not a valid (integer|datetime|etc.)')
334
+ # :message :: The message to use (default: 'is not a valid (integer|datetime|etc.)')
335
335
  def validates_schema_type(*atts)
336
336
  opts = {
337
337
  :tag => :schema_type,
@@ -362,7 +362,7 @@ module Sequel
362
362
  # database, as this suffers from a fairly obvious race condition.
363
363
  #
364
364
  # Possible Options:
365
- # * :message - The message to use (default: 'is already taken')
365
+ # :message :: The message to use (default: 'is already taken')
366
366
  def validates_uniqueness_of(*atts)
367
367
  opts = {
368
368
  :message => 'is already taken',
@@ -19,7 +19,7 @@ module Sequel
19
19
  # Options:
20
20
  # :allow_blank :: Whether to skip the validation if the value is blank. You should
21
21
  # make sure all objects respond to blank if you use this option, which you can do by:
22
- # Sequel.extension :blank
22
+ # Sequel.extension :blank
23
23
  # :allow_missing :: Whether to skip the validation if the attribute isn't a key in the
24
24
  # values hash. This is different from allow_nil, because Sequel only sends the attributes
25
25
  # in the values when doing an insert or update. If the attribute is not present, Sequel
@@ -44,8 +44,7 @@ module Sequel
44
44
  #
45
45
  # Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS.merge!(
46
46
  # :exact_length=>{:message=>lambda{|exact| I18n.t("errors.exact_length", :exact => exact)}},
47
- # :integer=>{:message=>lambda{I18n.t("errors.integer")}},
48
- # ...
47
+ # :integer=>{:message=>lambda{I18n.t("errors.integer")}}
49
48
  # )
50
49
  #
51
50
  # and then use something like this in your yaml translation file:
@@ -215,7 +214,7 @@ module Sequel
215
214
  # If you want to to a case insensitive uniqueness validation on a database that
216
215
  # is case sensitive by default, you can use:
217
216
  #
218
- # :where=>(proc do |ds, obj, cols|
217
+ # validates_unique :column, :where=>(proc do |ds, obj, cols|
219
218
  # ds.where(cols.map do |c|
220
219
  # v = obj.send(c)
221
220
  # v = v.downcase if v