Class: CommandModel::Model

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Naming
Includes:
ActiveModel::Conversion, ActiveModel::Validations
Defined in:
lib/command_model/model.rb

Defined Under Namespace

Classes: Parameter

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parameters = {}) ⇒ Model

Accepts a parameters hash or another of the same class. If another instance of the same class is passed in then the parameters are copied to the new object.



115
116
117
118
# File 'lib/command_model/model.rb', line 115

def initialize(parameters={})
  @typecast_errors = {}
  set_parameters parameters
end

Class Method Details

.attr_typecasting_writer(name, target_type) ⇒ Object

:nodoc



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/command_model/model.rb', line 51

def self.attr_typecasting_writer(name, target_type) #:nodoc
  eval "    def \#{name}=(value)\n      typecast_value = typecast_\#{target_type}(value)\n      if typecast_value\n        @typecast_errors.delete(\"\#{name}\")\n        @\#{name} = typecast_value\n      else\n        @typecast_errors[\"\#{name}\"] = \"\#{target_type}\"\n        @\#{name} = value\n      end\n      \n      @\#{name}\n    end\n  END_EVAL\nend\n"

.execute(attributes_or_command, &block) ⇒ Object

Executes a block of code if the command model is valid.

Accepts either a command model or a hash of attributes with which to create a new command model.

Examples

RenameUserCommand.execute(:login => "john") do |command|
  if allowed_to_rename_user?
    self. = command.
  else
    command.errors.add :base, "not allowed to rename"
  end
end


82
83
84
85
86
87
88
89
90
# File 'lib/command_model/model.rb', line 82

def self.execute(attributes_or_command, &block)
  command = if attributes_or_command.kind_of? self
    attributes_or_command
  else
    new(attributes_or_command)
  end
  
  command.call &block
end

.failure(error) ⇒ Object

Quickly create a failed command object. Requires one parameter with the description of what went wrong. This is used when the command takes no parameters to want to take advantage of the success? and errors properties of a command object.



105
106
107
108
109
110
# File 'lib/command_model/model.rb', line 105

def self.failure(error)
  new.tap do |instance|
    instance.execution_attempted!
    instance.errors.add(:base, error)
  end
end

.parameter(*args) ⇒ Object

Parameter requires one or more attributes as its first parameter(s). It accepts an options hash as its last parameter.

Options

  • typecast - The type of object to typecast to. Typecasts are built-in for integer, float, and date. Additional typecasts can be defined by defining a method typecast_#name for a typecast of #name.

  • validations - All other options are considered validations and are passed to ActiveModel::Validates.validates

Examples

parameter :gender
parameter :name, :presence => true
parameter :birthdate, :typecast => :date
parameter :height, :weight,
  :typecast => :integer,
  :presence => true,
  :numericality => { :greater_than_or_equal_to => 0 }


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/command_model/model.rb', line 29

def self.parameter(*args)
  options = args.last.kind_of?(Hash) ? args.pop.clone : {}
  typecast = options.delete(:typecast)

  args.each do |name|
    attr_reader name
    
    if typecast
      attr_typecasting_writer name, typecast
    else
      attr_writer name
    end
    validates name, options.clone if options.present? # clone options because validates mutates the hash :(
    parameters.push Parameter.new name, typecast, options
  end
end

.parametersObject

Returns array of all parameters defined for class



47
48
49
# File 'lib/command_model/model.rb', line 47

def self.parameters
  @parameters ||= []
end

.successObject

Quickly create a successful command object. This is used when the command takes no parameters to want to take advantage of the success? and errors properties of a command object.



95
96
97
98
99
# File 'lib/command_model/model.rb', line 95

def self.success
  new.tap do |instance|
    instance.execution_attempted!
  end
end

Instance Method Details

#call(&block) ⇒ Object

Executes the command by calling the method execute if the validations pass.



122
123
124
125
126
# File 'lib/command_model/model.rb', line 122

def call(&block)
  execute(&block) if valid?
  execution_attempted!
  self
end

#execute {|_self| ... } ⇒ Object

Performs the actual command execution. It does not test if the command parameters are valid. Typically, call should be called instead of calling execute directly.

execute should be overridden in descendent classes

Yields:

  • (_self)

Yield Parameters:



133
134
135
# File 'lib/command_model/model.rb', line 133

def execute
  yield self if block_given?
end

#execution_attempted!Object

Record that an attempt was made to execute this command whether or not it was successful.



139
140
141
# File 'lib/command_model/model.rb', line 139

def execution_attempted! #:nodoc:
  @execution_attempted = true
end

#execution_attempted?Boolean

True if execution has been attempted on this command

Returns:

  • (Boolean)


144
145
146
# File 'lib/command_model/model.rb', line 144

def execution_attempted?
  @execution_attempted
end

#parametersObject

Returns hash of all parameter names and values



154
155
156
157
158
# File 'lib/command_model/model.rb', line 154

def parameters
  self.class.parameters.each_with_object({}) do |parameter, hash|
    hash[parameter.name] = send(parameter.name)
  end
end

#persisted?Boolean

:nodoc:

Returns:

  • (Boolean)


169
170
171
# File 'lib/command_model/model.rb', line 169

def persisted?
  false
end

#set_parameters(hash_or_instance) ⇒ Object

Sets parameter(s) from hash or instance of same class



161
162
163
164
165
166
# File 'lib/command_model/model.rb', line 161

def set_parameters(hash_or_instance)
  parameters = extract_parameters_from_hash_or_instance(hash_or_instance)
  parameters.each do |k,v|
    send "#{k}=", v
  end
end

#success?Boolean

Command has been executed without errors

Returns:

  • (Boolean)


149
150
151
# File 'lib/command_model/model.rb', line 149

def success?
  execution_attempted? && errors.empty?
end