Class: Storefront::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/storefront/models/model.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, &block) ⇒ Model

Returns a new instance of Model.



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/storefront/models/model.rb', line 20

def initialize(options = {}, &block)
  @object = options[:object]
  @parent = options[:parent]
  if options[:keys].present?
    @keys   = options[:keys]
  elsif @object.is_a?(::OpenStruct) && @object.klass.present?
    @keys   = [@object.klass.to_s.underscore]
  else
    @keys   = [@object.class.name.underscore]
  end
end

Instance Attribute Details

#errorsObject (readonly)

Returns the value of attribute errors.



18
19
20
# File 'lib/storefront/models/model.rb', line 18

def errors
  @errors
end

#keysObject (readonly)

Returns the value of attribute keys.



18
19
20
# File 'lib/storefront/models/model.rb', line 18

def keys
  @keys
end

#objectObject (readonly)

Returns the value of attribute object.



18
19
20
# File 'lib/storefront/models/model.rb', line 18

def object
  @object
end

#parentObject (readonly)

Returns the value of attribute parent.



18
19
20
# File 'lib/storefront/models/model.rb', line 18

def parent
  @parent
end

Class Method Details

.model_names(array) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
# File 'lib/storefront/models/model.rb', line 4

def model_names(array)
  Array(array).flatten.map do |object|
    case object
    when ::Class
      (object.ancestors - object.included_modules).map { |i| i.name.underscore }
    when ::String, ::Symbol
      object
    else
      (object.class.ancestors - object.class.included_modules).map { |i| i.name.underscore }
    end
  end.flatten.compact.uniq
end

Instance Method Details

#column_for(method) ⇒ Object

Get a column object for a specified attribute method - if possible.



161
162
163
# File 'lib/storefront/models/model.rb', line 161

def column_for(method) #:nodoc:
  @object.column_for_attribute(method) if @object.respond_to?(:column_for_attribute)
end

#configObject



36
37
38
# File 'lib/storefront/models/model.rb', line 36

def config
  Storefront.configuration
end

#default(attribute) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/storefront/models/model.rb', line 126

def default(attribute)
  if @object.respond_to?(attribute)
    result = case macro_for(attribute)
    when :belongs_to, :has_one
      @object.send(attribute) || @object.send("build_#{attribute}")
    when :has_many
      @object.send(attribute.to_s.pluralize).build
    else
      @object.send(attribute)
    end
    result
  elsif @object.is_a?(::OpenStruct)
    result = ::OpenStruct.new
    result.klass = attribute.to_s.camelize
    @object.send("#{attribute}=", result)
    result
  else
    nil
  end
end

#default_input_type(method, options = {}) ⇒ Object

:nodoc:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/storefront/models/model.rb', line 64

def default_input_type(method, options = {}) #:nodoc:
  if column = column_for(method)
    # Special cases where the column type doesn't map to an input method.
    case column.type
    when :string
      return :password  if method.to_s =~ /password/
      return :country   if method.to_s =~ /country$/
      return :time_zone if method.to_s =~ /time_zone/
      return :email     if method.to_s =~ /email/
      return :url       if method.to_s =~ /^url$|^website$|_url$/
      return :phone     if method.to_s =~ /(phone|fax)/
      return :search    if method.to_s =~ /^search$/
    when :integer
      return :select    if reflection_for(method)
      return :numeric
    when :float, :decimal
      return :numeric
    when :timestamp
      return :datetime
    end
    
    # Try look for hints in options hash. Quite common senario: Enum keys stored as string in the database.
    return :select    if column.type == :string && options.key?(:collection)
    # Try 3: Assume the input name will be the same as the column type (e.g. string_input).
    return column.type
  else
    if @object
      return :select  if reflection_for(method)

      return :file    if is_file?(method, options)
    end

    return :select    if options.key?(:collection)
    return :password  if method.to_s =~ /password/
    return :string
  end
end

#default_string_options(method, type) ⇒ Object



234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/storefront/models/model.rb', line 234

def default_string_options(method, type)
  validation_max_limit = get_maxlength_for(method)
  column               = column_for(method)
  
  if type == :text
    {:rows => default_text_area_height, :cols => config.default_text_area_width}
  elsif type == :numeric || column.nil? || !column.respond_to?(:limit) || column.limit.nil?
    {:maxlength => validation_max_limit, :size => config.default_text_field_size}
  else
    {:maxlength => validation_max_limit || column.limit, :size => config.default_text_field_size}
  end
end

#errors_for(name) ⇒ Object



114
115
116
# File 'lib/storefront/models/model.rb', line 114

def errors_for(name)
  return @object.errors[name] if errors_on?(name)
end

#errors_on?(attribute, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/storefront/models/model.rb', line 60

def errors_on?(attribute, options = {})
  @object.respond_to?(:errors) ? @object.errors[attribute].present? : false
end

#file_methodsObject



110
111
112
# File 'lib/storefront/models/model.rb', line 110

def file_methods
  [:file?, :public_filename, :filename]
end

#get(attribute) ⇒ Object



44
45
46
# File 'lib/storefront/models/model.rb', line 44

def get(attribute)
  @object.send(attribute)
end

#get_maxlength_for(method) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/storefront/models/model.rb', line 185

def get_maxlength_for(method)
  validation = validations_for(method).find do |validation|
    (validation.respond_to?(:macro) && validation.macro == :validates_length_of) || # Rails 2 validation
    (validation.respond_to?(:kind) && validation.kind == :length) # Rails 3 validator
  end
  
  if validation
    validation.options[:maximum] || (validation.options[:within].present? ? validation.options[:within].max : nil)
  else
    nil
  end
end

#humanized_attribute_name(method) ⇒ Object

:nodoc:



118
119
120
121
122
123
124
# File 'lib/storefront/models/model.rb', line 118

def humanized_attribute_name(method) #:nodoc:
  if @object && @object.class.respond_to?(:human_attribute_name)
    @object.class.human_attribute_name(method.to_s)
  else
    method.to_s.send(config.label_method)
  end
end

#is_file?(method, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
105
106
107
108
# File 'lib/storefront/models/model.rb', line 102

def is_file?(method, options = {})
  @files ||= {}
  @files[method] ||= (options[:as].present? && options[:as] == :file) || begin
    file = @object.send(method) if @object && @object.respond_to?(method)
    file && file_methods.any?{|m| file.respond_to?(m)}
  end
end

#macro_for(method) ⇒ Object



154
155
156
157
# File 'lib/storefront/models/model.rb', line 154

def macro_for(method)
  reflection     = reflection_for(method)
  reflection ? reflection.macro : nil
end

#new_record?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/storefront/models/model.rb', line 32

def new_record?
  @object.respond_to?(:new_record?) && !@object.new_record?
end

#options_require_validation?(options) ⇒ Boolean

Returns:

  • (Boolean)


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/storefront/models/model.rb', line 217

def options_require_validation?(options)
  allow_blank = options[:allow_blank]
  return !allow_blank unless allow_blank.nil?
  if_condition = !options[:if].nil?
  condition = if_condition ? options[:if] : options[:unless]
  
  condition = if condition.respond_to?(:call)
                condition.call(@object)
              elsif condition.is_a?(::Symbol) && @object.respond_to?(condition)
                @object.send(condition)
              else
                condition
              end

  if_condition ? !!condition : !condition
end

#reflection_for(method) ⇒ Object

If an association method is passed in (f.input :author) try to find the reflection object.



150
151
152
# File 'lib/storefront/models/model.rb', line 150

def reflection_for(method) #:nodoc:
  @object.class.reflect_on_association(method) if @object.class.respond_to?(:reflect_on_association)
end

#required?(attribute) ⇒ Boolean

remove this, it’s for old rails

Returns:

  • (Boolean)


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/storefront/models/model.rb', line 199

def required?(attribute)
  attribute_sym = attribute.to_s.sub(/_id$/, '').to_sym

  if @object && @object.class.respond_to?(:reflect_on_validations_for)
    @object.class.reflect_on_validations_for(attribute_sym).any? do |validation|
      (validation.macro == :validates_presence_of || validation.macro == :validates_inclusion_of) &&
      validation.name == attribute_sym &&
      (validation.options.present? ? options_require_validation?(validation.options) : true)
    end
  else
    if @object && @object.class.respond_to?(:validators_on)
      !@object.class.validators_on(attribute_sym).find{|validator| (validator.kind == :presence || validator.kind == :inclusion) && (validator.options.present? ? options_require_validation?(validator.options) : true)}.nil?
    else
      true
    end
  end
end

#self_and_ancestor_namesObject



40
41
42
# File 'lib/storefront/models/model.rb', line 40

def self_and_ancestor_names
  @self_and_ancestor_names ||= self.class.model_names(@object)
end

#validation_message(attribute, key, options = {}) ⇒ Object



56
57
58
# File 'lib/storefront/models/model.rb', line 56

def validation_message(attribute, key, options = {})
  @object.errors.generate_message(attribute, key, options)
end

#validations_for(method, mode = :active) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/storefront/models/model.rb', line 165

def validations_for(method, mode = :active)
  # ActiveModel?
  validations = if @object && @object.class.respond_to?(:validators_on)
    @object.class.validators_on(method)
  else
    # ValidationReflection plugin?
    if @object && @object.class.respond_to?(:reflect_on_validations_for)
      @object.class.reflect_on_validations_for(method)
    else
      []
    end
  end
  
  validations = validations.select do |validation|
    (validation.options.present? ? options_require_validation?(validation.options) : true)
  end unless mode == :all
  
  return validations
end

#validators?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/storefront/models/model.rb', line 48

def validators?
  @object.class.respond_to?(:validators_on)
end

#validators_on(attribute) ⇒ Object



52
53
54
# File 'lib/storefront/models/model.rb', line 52

def validators_on(attribute)
  @object.class.validators_on(attribute)
end