Class: Vehicles::Make

Inherits:
Object
  • Object
show all
Defined in:
lib/vehicles/make.rb

Overview

A vehicle make, e.g. “Volkswagen”, and the models it builds. Immutable value object. Its models are built lazily once and cached.

make = Vehicles.make("Audi")
make.slug       # => "audi"
make.models     # => ["A3", "A4", "Q3", ...]
make.model("a3")# => #<Vehicles::Model "Audi A3">

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs) ⇒ Make

Returns a new instance of Make.



14
15
16
17
18
19
20
# File 'lib/vehicles/make.rb', line 14

def initialize(attrs)
  @name    = attrs["name"]
  @slug    = attrs["slug"]
  @aliases = Array(attrs["aliases"]).freeze
  @kinds   = Array(attrs["kinds"]).map(&:to_sym).freeze
  @raw_models = attrs["models"] || []
end

Instance Attribute Details

#aliasesObject (readonly)

Returns the value of attribute aliases.



12
13
14
# File 'lib/vehicles/make.rb', line 12

def aliases
  @aliases
end

#kindsObject (readonly)

Returns the value of attribute kinds.



12
13
14
# File 'lib/vehicles/make.rb', line 12

def kinds
  @kinds
end

#nameObject (readonly)

Returns the value of attribute name.



12
13
14
# File 'lib/vehicles/make.rb', line 12

def name
  @name
end

#slugObject (readonly)

Returns the value of attribute slug.



12
13
14
# File 'lib/vehicles/make.rb', line 12

def slug
  @slug
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



63
64
65
# File 'lib/vehicles/make.rb', line 63

def ==(other)
  other.is_a?(Make) && other.slug == slug
end

#hashObject



68
69
70
# File 'lib/vehicles/make.rb', line 68

def hash
  slug.hash
end

#inspectObject



72
73
74
# File 'lib/vehicles/make.rb', line 72

def inspect
  %(#<Vehicles::Make "#{name}">)
end

#model(query) ⇒ Object

Find one model within this make by exact (normalized) name or slug. “a3” / “A3” / “Q 3” resolve; partial input does NOT (so ‘model(“a”)` returns nil, not “A3” — important, since the vehicle_model validator relies on this). Fuzzy/partial matching lives in `Vehicles.search`.



48
49
50
51
52
53
# File 'lib/vehicles/make.rb', line 48

def model(query)
  q = Vehicles.normalize(query)
  return nil if q.empty?

  models.find { |m| Vehicles.normalize(m.name) == q || m.model_slug == q }
end

#model_names(**filters) ⇒ Object

Model display names — what you drop into a dropdown. => [“A3”, “A4”, …]



35
36
37
# File 'lib/vehicles/make.rb', line 35

def model_names(**filters)
  models(**filters).map(&:name)
end

#model_options(**filters) ⇒ Object

[label, value], …

for Rails ‘select`. => [[“A3”, “a3”], [“A4”, “a4”]]



40
41
42
# File 'lib/vehicles/make.rb', line 40

def model_options(**filters)
  models(**filters).map { |m| [m.name, m.model_slug] }
end

#models(kind: nil, body_type: nil) ⇒ Object

All models for this make, optionally filtered by kind/body_type. Returns Vehicles::Model objects, ordered by popularity (as built). The unfiltered list is memoized AND frozen — it’s shared process-wide, so a frozen array turns accidental caller mutation into a loud error instead of silently corrupting the dataset. Filtered calls return a fresh array.



27
28
29
30
31
32
# File 'lib/vehicles/make.rb', line 27

def models(kind: nil, body_type: nil)
  list = (@models ||= @raw_models.map { |m| Model.new(m, make: name, make_slug: slug) }.freeze)
  list = list.select { |m| m.kind == kind.to_sym }           if kind
  list = list.select { |m| m.body_type == body_type.to_sym } if body_type
  list
end

#to_hObject



55
56
57
# File 'lib/vehicles/make.rb', line 55

def to_h
  { name: name, slug: slug, kinds: kinds, models: model_names }
end

#to_sObject



59
60
61
# File 'lib/vehicles/make.rb', line 59

def to_s
  name
end