add instance_accessor option to ActiveSupport::Configurable#config_accessor
Changes: * Add `instance_accessor` option to opt out of the instance writer and instance reader methods. * Raises a NameError if the name of the attribute is not valid. * Update documentation and tests. * Add CHANGELOG entry in activesupport.
This commit is contained in:
parent
8359a2f981
commit
5e1d40f773
@ -1,5 +1,17 @@
|
|||||||
## Rails 4.0.0 (unreleased) ##
|
## Rails 4.0.0 (unreleased) ##
|
||||||
|
|
||||||
|
* Add `:instance_accessor` option for `config_accessor`.
|
||||||
|
|
||||||
|
class User
|
||||||
|
include ActiveSupport::Configurable
|
||||||
|
config_accessor :allowed_access, instance_accessor: false
|
||||||
|
end
|
||||||
|
|
||||||
|
User.new.allowed_access = true # => NoMethodError
|
||||||
|
User.new.allowed_access # => NoMethodError
|
||||||
|
|
||||||
|
*Francesco Rodriguez*
|
||||||
|
|
||||||
* ActionView::Helpers::NumberHelper methods have been moved to ActiveSupport::NumberHelper and are now available via
|
* ActionView::Helpers::NumberHelper methods have been moved to ActiveSupport::NumberHelper and are now available via
|
||||||
Numeric#to_s. Numeric#to_s now accepts the formatting options :phone, :currency, :percentage, :delimited,
|
Numeric#to_s. Numeric#to_s now accepts the formatting options :phone, :currency, :percentage, :delimited,
|
||||||
:rounded, :human, and :human_size. *Andrew Mutz*
|
:rounded, :human, and :human_size. *Andrew Mutz*
|
||||||
|
@ -37,29 +37,77 @@ def configure
|
|||||||
yield config
|
yield config
|
||||||
end
|
end
|
||||||
|
|
||||||
# Allows you to add shortcut so that you don't have to refer to attribute through config.
|
# Allows you to add shortcut so that you don't have to refer to attribute
|
||||||
# Also look at the example for config to contrast.
|
# through config. Also look at the example for config to contrast.
|
||||||
|
#
|
||||||
|
# Defines both class and instance config accessors.
|
||||||
#
|
#
|
||||||
# class User
|
# class User
|
||||||
# include ActiveSupport::Configurable
|
# include ActiveSupport::Configurable
|
||||||
# config_accessor :allowed_access
|
# config_accessor :allowed_access
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
|
# User.allowed_access # => nil
|
||||||
|
# User.allowed_access = false
|
||||||
|
# User.allowed_access # => false
|
||||||
|
#
|
||||||
# user = User.new
|
# user = User.new
|
||||||
|
# user.allowed_access # => false
|
||||||
# user.allowed_access = true
|
# user.allowed_access = true
|
||||||
# user.allowed_access # => true
|
# user.allowed_access # => true
|
||||||
#
|
#
|
||||||
|
# User.allowed_access # => false
|
||||||
|
#
|
||||||
|
# The attribute name must be a valid method name in Ruby.
|
||||||
|
#
|
||||||
|
# class User
|
||||||
|
# include ActiveSupport::Configurable
|
||||||
|
# config_accessor :"1_Badname"
|
||||||
|
# end
|
||||||
|
# # => NameError: invalid config attribute name
|
||||||
|
#
|
||||||
|
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
||||||
|
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
||||||
|
#
|
||||||
|
# class User
|
||||||
|
# include ActiveSupport::Configurable
|
||||||
|
# config_accessor :allowed_access, instance_reader: false, instance_writer: false
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# User.allowed_access = false
|
||||||
|
# User.allowed_access # => false
|
||||||
|
#
|
||||||
|
# User.new.allowed_access = true # => NoMethodError
|
||||||
|
# User.new.allowed_access # => NoMethodError
|
||||||
|
#
|
||||||
|
# Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
|
||||||
|
#
|
||||||
|
# class User
|
||||||
|
# include ActiveSupport::Configurable
|
||||||
|
# config_accessor :allowed_access, instance_accessor: false
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# User.allowed_access = false
|
||||||
|
# User.allowed_access # => false
|
||||||
|
#
|
||||||
|
# User.new.allowed_access = true # => NoMethodError
|
||||||
|
# User.new.allowed_access # => NoMethodError
|
||||||
def config_accessor(*names)
|
def config_accessor(*names)
|
||||||
options = names.extract_options!
|
options = names.extract_options!
|
||||||
|
|
||||||
names.each do |name|
|
names.each do |name|
|
||||||
|
raise NameError.new('invalid config attribute name') unless name =~ /^[_A-Za-z]\w*$/
|
||||||
|
|
||||||
reader, line = "def #{name}; config.#{name}; end", __LINE__
|
reader, line = "def #{name}; config.#{name}; end", __LINE__
|
||||||
writer, line = "def #{name}=(value); config.#{name} = value; end", __LINE__
|
writer, line = "def #{name}=(value); config.#{name} = value; end", __LINE__
|
||||||
|
|
||||||
singleton_class.class_eval reader, __FILE__, line
|
singleton_class.class_eval reader, __FILE__, line
|
||||||
singleton_class.class_eval writer, __FILE__, line
|
singleton_class.class_eval writer, __FILE__, line
|
||||||
class_eval reader, __FILE__, line unless options[:instance_reader] == false
|
|
||||||
class_eval writer, __FILE__, line unless options[:instance_writer] == false
|
unless options[:instance_accessor] == false
|
||||||
|
class_eval reader, __FILE__, line unless options[:instance_reader] == false
|
||||||
|
class_eval writer, __FILE__, line unless options[:instance_writer] == false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -79,7 +127,6 @@ def config_accessor(*names)
|
|||||||
#
|
#
|
||||||
# user.config.allowed_access # => true
|
# user.config.allowed_access # => true
|
||||||
# user.config.level # => 1
|
# user.config.level # => 1
|
||||||
#
|
|
||||||
def config
|
def config
|
||||||
@_config ||= self.class.config.inheritable_copy
|
@_config ||= self.class.config.inheritable_copy
|
||||||
end
|
end
|
||||||
|
@ -5,7 +5,8 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase
|
|||||||
class Parent
|
class Parent
|
||||||
include ActiveSupport::Configurable
|
include ActiveSupport::Configurable
|
||||||
config_accessor :foo
|
config_accessor :foo
|
||||||
config_accessor :bar, :instance_reader => false, :instance_writer => false
|
config_accessor :bar, instance_reader: false, instance_writer: false
|
||||||
|
config_accessor :baz, instance_accessor: false
|
||||||
end
|
end
|
||||||
|
|
||||||
class Child < Parent
|
class Child < Parent
|
||||||
@ -19,13 +20,13 @@ class Child < Parent
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "adds a configuration hash" do
|
test "adds a configuration hash" do
|
||||||
assert_equal({ :foo => :bar }, Parent.config)
|
assert_equal({ foo: :bar }, Parent.config)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "adds a configuration hash to a module as well" do
|
test "adds a configuration hash to a module as well" do
|
||||||
mixin = Module.new { include ActiveSupport::Configurable }
|
mixin = Module.new { include ActiveSupport::Configurable }
|
||||||
mixin.config.foo = :bar
|
mixin.config.foo = :bar
|
||||||
assert_equal({ :foo => :bar }, mixin.config)
|
assert_equal({ foo: :bar }, mixin.config)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "configuration hash is inheritable" do
|
test "configuration hash is inheritable" do
|
||||||
@ -39,8 +40,12 @@ class Child < Parent
|
|||||||
|
|
||||||
test "configuration accessors is not available on instance" do
|
test "configuration accessors is not available on instance" do
|
||||||
instance = Parent.new
|
instance = Parent.new
|
||||||
|
|
||||||
assert !instance.respond_to?(:bar)
|
assert !instance.respond_to?(:bar)
|
||||||
assert !instance.respond_to?(:bar=)
|
assert !instance.respond_to?(:bar=)
|
||||||
|
|
||||||
|
assert !instance.respond_to?(:baz)
|
||||||
|
assert !instance.respond_to?(:baz=)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "configuration hash is available on instance" do
|
test "configuration hash is available on instance" do
|
||||||
@ -71,6 +76,15 @@ class Child < Parent
|
|||||||
assert_method_defined child.new.config, :bar
|
assert_method_defined child.new.config, :bar
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "should raise name error if attribute name is invalid" do
|
||||||
|
assert_raises NameError do
|
||||||
|
Class.new do
|
||||||
|
include ActiveSupport::Configurable
|
||||||
|
config_accessor "invalid attribute name"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def assert_method_defined(object, method)
|
def assert_method_defined(object, method)
|
||||||
methods = object.public_methods.map(&:to_s)
|
methods = object.public_methods.map(&:to_s)
|
||||||
assert methods.include?(method.to_s), "Expected #{methods.inspect} to include #{method.to_s.inspect}"
|
assert methods.include?(method.to_s), "Expected #{methods.inspect} to include #{method.to_s.inspect}"
|
||||||
@ -80,4 +94,4 @@ def assert_method_not_defined(object, method)
|
|||||||
methods = object.public_methods.map(&:to_s)
|
methods = object.public_methods.map(&:to_s)
|
||||||
assert !methods.include?(method.to_s), "Expected #{methods.inspect} to not include #{method.to_s.inspect}"
|
assert !methods.include?(method.to_s), "Expected #{methods.inspect} to not include #{method.to_s.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
Loading…
Reference in New Issue
Block a user