Skip to content

Commit

Permalink
Allow proc default values that depend on other values
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrocarmona committed Jul 25, 2024
1 parent 7772732 commit 980c261
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 7 deletions.
14 changes: 10 additions & 4 deletions lib/sequel/plugins/defaults_setter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ module Plugins
# album.values # => {}
# album.a
# album.values # => {:a => Date.today}
#
#
# Usage:
#
# # Make all model subclass instances set defaults (called before loading subclasses)
# Sequel::Model.plugin :defaults_setter
#
# # Make the Album class set defaults
# # Make the Album class set defaults
# Album.plugin :defaults_setter
module DefaultsSetter
# Set the default values based on the model schema. Options:
Expand All @@ -76,7 +76,7 @@ module ClassMethods
def cache_default_values?
@cache_default_values
end

# Freeze default values when freezing model class
def freeze
@default_values.freeze
Expand Down Expand Up @@ -133,7 +133,13 @@ module InstanceMethods
def [](k)
if new? && !values.has_key?(k)
v = model.default_values.fetch(k){return}
v = v.call if v.respond_to?(:call)
if v.respond_to?(:call)
if v.arity == 1
v = v.call(self)
else
v = v.call
end
end
values[k] = v if model.cache_default_values?
v
else
Expand Down
12 changes: 9 additions & 3 deletions spec/extensions/defaults_setter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ def db.supports_schema_parsing?() true end
def db.schema(*) [] end
db.singleton_class.send(:alias_method, :schema, :schema)
@c = c = Class.new(Sequel::Model(db[:foo]))
@c.instance_variable_set(:@db_schema, {:a=>{}})
@c.instance_variable_set(:@db_schema, {:a=>{}, :b=>{}})
@c.plugin :defaults_setter
@c.columns :a
@c.columns :a, :b
@pr = proc do |x|
db.define_singleton_method(:schema){|*| [[:id, {:primary_key=>true}], [:a, {:ruby_default => x, :primary_key=>false}]]}
db.define_singleton_method(:schema){|*| [[:id, {:primary_key=>true}], [:a, {:ruby_default => x, :primary_key=>false}], [:b, {:primary_key=>false}]]}
db.singleton_class.send(:alias_method, :schema, :schema)
c.dataset = c.dataset; c
end
Expand Down Expand Up @@ -181,6 +181,12 @@ def db.schema(*) [] end
c.new.a.must_equal 2
end

it "should allow proc default values that depend on other values" do
@pr.call(2)
@c.default_values[:a] = proc{ |instance| instance.b * 2 }
@c.new(b: 5).a.must_equal 10
end

it "should set default value upon initialization when plugin loaded without dataset" do
db = @db
@c = c = Class.new(Sequel::Model)
Expand Down

0 comments on commit 980c261

Please sign in to comment.