module Pancake module Mixins module Publish class ActionOptions attr_reader :params, :formats, :default CONFIG_OPTIONS = [:provides, :only_provides] # Generates a new instance of the class. This instance encapsulates the # options and logic needed to validate the parameters being input into # a controller action. First argument is a list of symbols for the # formats it supports. The second is hash of options. Typically this # hash is generated by the publish declaration in a controller. # # TODO: Allow params to be grouped together # # @api private def initialize(default_formats, opts) # Extract the params — excluding configuration — and turn the keys into # strings. Additionally, check to see if someone has passed in a a raw # value rather than using one of our as_* methods. @params = opts.inject({}) do |memo, opt| unless CONFIG_OPTIONS.include? opt[0] unless opt[1].is_a?(Array) raise "Parameter values must be specified with an as_* method. You passed in a #{opt[1].class.to_s}" end memo[opt[0].to_s] = opt[1] end memo end @formats = extract_format_options(default_formats, opts) end # Accepts a hash of parameters and replaces each entry with it’s # coerced or default value. If an expected param is missing, it will # raise an error. # # TODO: Flag missing params rather than just raising an error # TODO: Allow defaults to be dynamically generated, i.e. method call # # @api private def validate_and_coerce(incoming_params) missing = [] params.each do |name, config| type, default, opts = config value = incoming_params[name] if !value.nil? && value != "" incoming_params[name] = send("validate_and_coerce_#{type}", value, opts) else if default == :req missing << [name, type] elsif default != :opt incoming_params[name] = default end end end [incoming_params, missing] end private # Accepts a string and turns it into an integer. The opts argument is # only there to satisfy the interface. it is not used. # # @api private def validate_and_coerce_integer(value, opts) value.to_i end # Accepts a string and turns it into a date. The opts argument is # only there to satisfy the interface. it is not used. # # @api private def validate_and_coerce_date(value, opts) Date.parse(value) end # Turns the incoming value into a string. The opts argument is # only there to satisfy the interface. it is not used. # # @api private def validate_and_coerce_string(value, opts) value.to_s end # Extracts the format options from a hash. It is used to compile the # list of formats that an action can provide. It accepts an array of # symbols representing the base formats and will add to or overwrite # them based on the options in the hash. # # @api private def extract_format_options(defaults, opts) @formats = if opts[:provides] defaults + [opts[:provides]].flatten elsif opts[:only_provides] [opts[:only_provides]].flatten else defaults end end end # ActionOptions end # Publish end # Mixins end # Pancake