Class: Vehicles::Model

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

Overview

A single vehicle nameplate, e.g. “Volkswagen Golf”. A lightweight, immutable value object — no ActiveRecord, no mutation. Reads like English on purpose.

car = Vehicles.find("vw golf")
car.make        # => "Volkswagen"
car.name        # => "Golf"
car.full_name   # => "Volkswagen Golf"
car.body_type   # => :hatchback
car.suv?        # => false

Constant Summary collapse

KINDS =

Vehicle kinds (RDW ‘voertuigsoort`). Today the bundled data is all :car; the shape already supports the rest for when those packs land.

%i[car motorcycle van truck pickup trailer bus moped quad trike].freeze
BODY_TYPES =

Body types — the sub-classification within a kind. For cars these are the familiar shapes; motorcycle styles (:naked, :adventure, …) reuse this field.

%i[
  hatchback sedan wagon suv mpv coupe convertible roadster pickup van
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs, make:, make_slug:) ⇒ Model

Returns a new instance of Model.

Parameters:

  • attrs (Hash)

    one model entry from the dataset (name/slug/kind/body_type)

  • make (String)

    the parent make’s display name

  • make_slug (String)

    the parent make’s slug (for the composite slug)



29
30
31
32
33
34
35
36
37
# File 'lib/vehicles/model.rb', line 29

def initialize(attrs, make:, make_slug:)
  @make       = make
  @make_slug  = make_slug
  @name       = attrs["name"]
  @model_slug = attrs["slug"]
  @kind       = (attrs["kind"]      || "car").to_sym
  @body_type  = (attrs["body_type"] || "hatchback").to_sym
  freeze
end

Instance Attribute Details

#body_typeObject (readonly)

Returns the value of attribute body_type.



24
25
26
# File 'lib/vehicles/model.rb', line 24

def body_type
  @body_type
end

#kindObject (readonly)

Returns the value of attribute kind.



24
25
26
# File 'lib/vehicles/model.rb', line 24

def kind
  @kind
end

#makeObject (readonly)

Returns the value of attribute make.



24
25
26
# File 'lib/vehicles/model.rb', line 24

def make
  @make
end

#make_slugObject (readonly)

Returns the value of attribute make_slug.



24
25
26
# File 'lib/vehicles/model.rb', line 24

def make_slug
  @make_slug
end

#model_slugObject (readonly)

The bare model slug (“golf”), used as the value in ‘model_options`.



51
52
53
# File 'lib/vehicles/model.rb', line 51

def model_slug
  @model_slug
end

#nameObject (readonly)

Returns the value of attribute name.



24
25
26
# File 'lib/vehicles/model.rb', line 24

def name
  @name
end

Instance Method Details

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

Value-object equality — two models with the same slug are equal.



64
65
66
# File 'lib/vehicles/model.rb', line 64

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

#full_nameObject Also known as: to_s

“Volkswagen Golf” — the natural label for a model on its own.



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

def full_name
  "#{make} #{name}"
end

#hashObject



69
70
71
# File 'lib/vehicles/model.rb', line 69

def hash
  slug.hash
end

#image(year: nil, color: nil) ⇒ Object

Image URL, optionally year-/color-accurate. nil without hosted data.



94
95
96
# File 'lib/vehicles/model.rb', line 94

def image(year: nil, color: nil)
  Vehicles.resolve(:image, self, year: year, color: color)
end

#inspectObject



73
74
75
# File 'lib/vehicles/model.rb', line 73

def inspect
  %(#<Vehicles::Model "#{full_name}" #{body_type}>)
end

#segmentObject

Editorial market segment, e.g. :hot_hatch, :supercar. nil without hosted data.



89
90
91
# File 'lib/vehicles/model.rb', line 89

def segment
  Vehicles.resolve(:segment, self)
end

#slugObject

Composite, stable slug: “volkswagen-golf”.



46
47
48
# File 'lib/vehicles/model.rb', line 46

def slug
  "#{make_slug}-#{@model_slug}"
end

#to_hObject



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

def to_h
  { make: make, model: name, slug: slug, kind: kind, body_type: body_type }
end

#yearsObject

Production years as a Range, e.g. 1974..2024. nil without hosted data.



84
85
86
# File 'lib/vehicles/model.rb', line 84

def years
  Vehicles.resolve(:years, self)
end