diff --git a/lib/options_model/base.rb b/lib/options_model/base.rb index 02a06e2..7249413 100644 --- a/lib/options_model/base.rb +++ b/lib/options_model/base.rb @@ -10,9 +10,7 @@ class Base validate do self.class.attribute_names.each do |attribute_name| attribute = public_send(attribute_name) - if attribute.is_a?(self.class) && attribute.invalid? - errors.add attribute_name, :invalid - end + errors.add attribute_name, :invalid if attribute.is_a?(self.class) && attribute.invalid? end end @@ -22,14 +20,14 @@ def ==(other) nested_attributes == other.nested_attributes && unused_attributes == other.unused_attributes end - alias :eql? :== + alias eql? == def hash [attributes, nested_attributes, unused_attributes].hash end def inspect - "#<#{self.class.name}:OptionsModel #{self.to_h}>" + "#<#{self.class.name}:OptionsModel #{to_h}>" end def self.inspect diff --git a/lib/options_model/concerns/attribute_assignment.rb b/lib/options_model/concerns/attribute_assignment.rb index 380c246..041badf 100644 --- a/lib/options_model/concerns/attribute_assignment.rb +++ b/lib/options_model/concerns/attribute_assignment.rb @@ -18,9 +18,7 @@ def initialize_dup(other) def update(other) return unless other - unless other.respond_to?(:to_h) - raise ArgumentError, "#{other} must be respond to `to_h`" - end + raise ArgumentError, "#{other} must be respond to `to_h`" unless other.respond_to?(:to_h) other.to_h.each do |k, v| if respond_to?("#{k}=") @@ -47,9 +45,7 @@ def []=(key, val) end def fetch(key, default = nil) - if self.class.attribute_names.exclude?(key.to_sym) && default.nil? && !block_given? - raise KeyError, "attribute not found" - end + raise KeyError, "attribute not found" if self.class.attribute_names.exclude?(key.to_sym) && default.nil? && !block_given? value = respond_to?(key) ? public_send(key) : nil return value if value diff --git a/lib/options_model/concerns/attributes.rb b/lib/options_model/concerns/attributes.rb index 948064a..1cd7aa1 100644 --- a/lib/options_model/concerns/attributes.rb +++ b/lib/options_model/concerns/attributes.rb @@ -16,10 +16,9 @@ def attribute(name, cast_type, default: nil, array: false) attribute_defaults[name] = default default_extractor = - case - when default.respond_to?(:call) + if default.respond_to?(:call) ".call" - when default.duplicable? + elsif default.duplicable? ".deep_dup" else "" @@ -55,13 +54,11 @@ def #{name}=(value) end STR - if cast_type == :boolean - generated_attribute_methods.send :alias_method, :"#{name}?", name - end + generated_attribute_methods.send :alias_method, :"#{name}?", name if cast_type == :boolean end end - self.attribute_names_for_inlining << name + attribute_names_for_inlining << name self end @@ -69,9 +66,8 @@ def #{name}=(value) def enum_attribute(name, enum, default: nil, allow_nil: false) check_not_finalized! - unless enum.is_a?(Array) && enum.any? - raise ArgumentError, "enum should be an Array and can't empty" - end + raise ArgumentError, "enum should be an Array and can't empty" unless enum.is_a?(Array) && enum.any? + enum = enum.map(&:to_s) attribute name, :string, default: default @@ -80,11 +76,11 @@ def enum_attribute(name, enum, default: nil, allow_nil: false) generated_class_methods.synchronize do generated_class_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 def #{pluralized_name} - %w(#{enum.join(" ")}).freeze + %w(#{enum.join(' ')}).freeze end STR - validates name, inclusion: {in: enum}, allow_nil: allow_nil + validates name, inclusion: { in: enum }, allow_nil: allow_nil end self @@ -93,17 +89,15 @@ def #{pluralized_name} def embeds_one(name, class_name: nil, anonymous_class: nil) check_not_finalized! - if class_name.blank? && anonymous_class.nil? - raise ArgumentError, "must provide at least one of `class_name` or `anonymous_class`" - end + raise ArgumentError, "must provide at least one of `class_name` or `anonymous_class`" if class_name.blank? && anonymous_class.nil? name = name.to_sym check_name_validity! name - if class_name.present? - nested_classes[name] = class_name.constantize + nested_classes[name] = if class_name.present? + class_name.constantize else - nested_classes[name] = anonymous_class + anonymous_class end generated_attribute_methods.synchronize do @@ -130,7 +124,7 @@ def #{name}=(value) STR end - self.attribute_names_for_nesting << name + attribute_names_for_nesting << name self end @@ -160,60 +154,56 @@ def finalized? end def finalize!(nested = true) - if nested - nested_classes.values.each(&:finalize!) - end + nested_classes.values.each(&:finalize!) if nested @finalized = true end protected - def check_name_validity!(symbolized_name) - if dangerous_attribute_method?(symbolized_name) - raise ArgumentError, "#{symbolized_name} is defined by #{OptionsModel::Base}. Check to make sure that you don't have an attribute or method with the same name." - end + def check_name_validity!(symbolized_name) + if dangerous_attribute_method?(symbolized_name) + raise ArgumentError, "#{symbolized_name} is defined by #{OptionsModel::Base}. Check to make sure that you don't have an attribute or method with the same name." + end - if attribute_names_for_inlining.include?(symbolized_name) || attribute_names_for_nesting.include?(symbolized_name) - raise ArgumentError, "duplicate define attribute `#{symbolized_name}`" + if attribute_names_for_inlining.include?(symbolized_name) || attribute_names_for_nesting.include?(symbolized_name) + raise ArgumentError, "duplicate define attribute `#{symbolized_name}`" + end end - end - def check_not_finalized! - if finalized? - raise "can't modify finalized #{self}" + def check_not_finalized! + raise "can't modify finalized #{self}" if finalized? end - end - # A method name is 'dangerous' if it is already (re)defined by OptionsModel, but - # not by any ancestors. (So 'puts' is not dangerous but 'save' is.) - def dangerous_attribute_method?(name) # :nodoc: - method_defined_within?(name, OptionsModel::Base) - end + # A method name is 'dangerous' if it is already (re)defined by OptionsModel, but + # not by any ancestors. (So 'puts' is not dangerous but 'save' is.) + def dangerous_attribute_method?(name) # :nodoc: + method_defined_within?(name, OptionsModel::Base) + end - def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc: - if klass.method_defined?(name) || klass.private_method_defined?(name) - if superklass.method_defined?(name) || superklass.private_method_defined?(name) - klass.instance_method(name).owner != superklass.instance_method(name).owner + def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc: + if klass.method_defined?(name) || klass.private_method_defined?(name) + if superklass.method_defined?(name) || superklass.private_method_defined?(name) + klass.instance_method(name).owner != superklass.instance_method(name).owner + else + true + end else - true + false end - else - false end - end - def generated_attribute_methods - @generated_attribute_methods ||= Module.new { - extend Mutex_m - }.tap { |mod| include mod } - end + def generated_attribute_methods + @generated_attribute_methods ||= Module.new do + extend Mutex_m + end.tap { |mod| include mod } + end - def generated_class_methods - @generated_class_methods ||= Module.new { - extend Mutex_m - }.tap { |mod| extend mod } - end + def generated_class_methods + @generated_class_methods ||= Module.new do + extend Mutex_m + end.tap { |mod| extend mod } + end end end end diff --git a/lib/options_model/concerns/serialization.rb b/lib/options_model/concerns/serialization.rb index 781397a..940ed65 100644 --- a/lib/options_model/concerns/serialization.rb +++ b/lib/options_model/concerns/serialization.rb @@ -35,7 +35,7 @@ def load(yaml) return new unless yaml return new unless yaml.is_a?(String) && /^---/.match?(yaml) - hash = YAML.load(yaml) || Hash.new + hash = YAML.safe_load(yaml) || {} unless hash.is_a? Hash raise ArgumentError, diff --git a/options_model.gemspec b/options_model.gemspec index 09be78a..c6b0502 100644 --- a/options_model.gemspec +++ b/options_model.gemspec @@ -1,6 +1,6 @@ # frozen_string_literal: true -$:.push File.expand_path("../lib", __FILE__) +$LOAD_PATH.push File.expand_path("lib", __dir__) # Maintain your gem's version: require "options_model/version" diff --git a/test/dummy/config/environments/production.rb b/test/dummy/config/environments/production.rb index 78d2f09..cd5d399 100644 --- a/test/dummy/config/environments/production.rb +++ b/test/dummy/config/environments/production.rb @@ -45,7 +45,7 @@ config.log_level = :debug # Prepend all log lines with the following tags. - config.log_tags = [ :request_id ] + config.log_tags = [:request_id] # Use a different cache store in production. # config.cache_store = :mem_cache_store diff --git a/test/dummy/config/spring.rb b/test/dummy/config/spring.rb index ff5ba06..c5933e4 100644 --- a/test/dummy/config/spring.rb +++ b/test/dummy/config/spring.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -%w( +%w[ .ruby-version .rbenv-vars tmp/restart.txt tmp/caching-dev.txt -).each { |path| Spring.watch(path) } +].each { |path| Spring.watch(path) } diff --git a/test/test_helper.rb b/test/test_helper.rb index 078c5a9..f333899 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require File.expand_path("../../test/dummy/config/environment.rb", __FILE__) +require File.expand_path("../test/dummy/config/environment.rb", __dir__) require "rails/test_help" # Filter out Minitest backtrace while allowing backtrace from other libraries @@ -11,7 +11,7 @@ # Load fixtures from the engine if ActiveSupport::TestCase.respond_to?(:fixture_path=) - ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__) + ActiveSupport::TestCase.fixture_path = File.expand_path("fixtures", __dir__) ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files" ActiveSupport::TestCase.fixtures :all