lib/chozo/varia_model.rb in chozo-0.4.0 vs lib/chozo/varia_model.rb in chozo-0.4.1
- old
+ new
@@ -4,20 +4,45 @@
module Chozo
# @author Jamie Winsor <jamie@vialstudios.com>
module VariaModel
module ClassMethods
+ ASSIGNMENT_MODES = [
+ :whitelist,
+ :carefree
+ ]
+
# @return [HashWithIndifferentAccess]
def attributes
@attributes ||= Hashie::Mash.new
end
# @return [HashWithIndifferentAccess]
def validations
@validations ||= HashWithIndifferentAccess.new
end
+ # @return [Symbol]
+ def assignment_mode
+ @assignment_mode ||= :whitelist
+ end
+
+ # Set the attribute mass assignment mode
+ # * :whitelist - only attributes defined on the class will have values set
+ # * :carefree - values will be set for attributes that are not explicitly defined
+ # in the class definition
+ #
+ # @param [Symbol] mode
+ # an assignment mode to use @see {ASSIGNMENT_MODES}
+ def set_assignment_mode(mode)
+ unless ASSIGNMENT_MODES.include?(mode)
+ raise ArgumentError, "unknown assignment mode: #{mode}"
+ end
+
+ @assignment_mode = mode
+ end
+
# @param [#to_s] name
# @option options [Symbol, Array<Symbol>] :type
# @option options [Boolean] :required
# @option options [Object] :default
# @option options [Proc] :coerce
@@ -170,15 +195,15 @@
def errors
@errors ||= HashWithIndifferentAccess.new
end
def mass_assign(new_attrs = {})
- attributes.dotted_paths.each do |dotted_path|
- value = new_attrs.dig(dotted_path)
- next if value.nil?
-
- set_attribute(dotted_path, value)
+ case self.class.assignment_mode
+ when :whitelist
+ whitelist_assign(new_attrs)
+ when :carefree
+ carefree_assign(new_attrs)
end
end
alias_method :attributes=, :mass_assign
# @param [#to_s] key
@@ -231,8 +256,23 @@
# @param [String] attribute
# @param [String] message
def add_error(attribute, message)
self.errors[attribute] ||= Array.new
self.errors[attribute] << message
- end
+ end
+
+ private
+
+ def carefree_assign(new_attrs = {})
+ attributes.deep_merge!(new_attrs)
+ end
+
+ def whitelist_assign(new_attrs = {})
+ attributes.dotted_paths.each do |dotted_path|
+ value = new_attrs.dig(dotted_path)
+ next if value.nil?
+
+ set_attribute(dotted_path, value)
+ end
+ end
end
end