Created
July 31, 2018 00:56
-
-
Save jmoglesby/c6cd028973e7cf169ce0dfa81634749e to your computer and use it in GitHub Desktop.
Example code: The "Item" model from www.speedie.equipment
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Item < ApplicationRecord | |
belongs_to :item_type | |
belongs_to :location | |
delegate :campus, to: :location | |
has_many :item_comments, dependent: :destroy | |
has_many :service_events, dependent: :destroy | |
has_one :last_service_event, -> { order(service_date: :desc, created_at: :desc) }, class_name: "ServiceEvent" | |
has_many :calibration_events, dependent: :destroy | |
has_one :last_calibration_event, -> { order(date_performed: :desc, created_at: :desc) }, class_name: "CalibrationEvent" | |
has_many :location_changes, dependent: :destroy | |
has_one :last_location_change, -> { order(date_of_change: :desc, created_at: :desc) }, class_name: "LocationChange" | |
# kaminari gem paginates search results - 10 items per page | |
paginates_per 10 | |
# Disallow duplicate serial_numbers | |
validates :serial_number, uniqueness: true, allow_blank: true | |
# Look into whether I need to cleanup old, uneeded | |
# paper_trail version records to avoid clutter | |
has_paper_trail | |
# If item is edited and location_id is changed in the edit, this hook saves the info | |
# to create a location_change record, unless the change in location_id comes directly | |
# from a location_change record creation | |
after_save :store_location_change, if: :location_id_changed?, unless: :skip_location_change_create | |
# skip_location_change_create is set to 'true' in location_changes_controller after | |
# creation of a new location_change record to avoid duplicating/overwriting upon item.save | |
attr_accessor :skip_location_change_create | |
# DO NOT add things to the middle of an enum list, only to the end; | |
# adding to the middle would change the array value of each option which | |
# would change the value of any option after it in the list on all items | |
# QUESTION: Should these values be enum'd on item_type instead of here??? | |
enum sieve_type: ['Fine', 'Coarse'] | |
enum fine_sieve_opening_size: ['#400', '#325', '#270', '#200', '#150', '#140', '#120', '#100', | |
'#80', '#60', '#50', '#45', '#40', '#35', '#30', '#25', '#20', | |
'#18', '#16', '#14', '#12', '#10', '#8', '#7', '#6' | |
] | |
enum coarse_sieve_opening_size: ['4"', '3"', '2 1/2"', '2"', '1 3/4"', '1 1/2"', '1 1/4"', | |
'1"', '7/8"', '3/4"', '5/8"', '1/2"', '7/16"', '3/8"', | |
'5/16"', '1/4"', '1/8"', '0.265"', '#4' | |
] | |
enum sieve_diameter: ['18 inch', '12 inch', '8 inch', '3 inch', 'Gilson'] | |
enum flask_type: ['Rice', 'SpG', 'Other'] | |
enum volume: ['10ml', '24ml', '25ml', '100ml', '250ml', '400ml', '450ml', '500ml', '1000ml', '2000ml', '4000ml'] | |
enum caliper_type: ['Axial', 'Digital', 'Dial', 'Proportional'] | |
enum caliper_size: ['(12")', '(6")'] | |
enum gauge_type: ['(Digital)', '(Dial)'] | |
enum thermometer_type: ['Mercury', 'PRT', 'Thermistor', 'Thermocouple', 'Infrared', 'Pocket'] | |
enum scale_resolution: ['1kg', '5g', '1g', '0.5g', '0.1g', '0.01g', '0.001g'] | |
enum scale_range: ['300lb', '110lb', '20kg', '15kg', '12kg', '500g', '200g', '220lb', '1000g'] | |
enum groove_tool_type: ['AASHTO', 'ASTM'] | |
enum operation_type: ['Manual', 'Automatic'] | |
enum marshall_compaction_pedestal_number: ['Single', 'Double'] | |
enum proctor_mold_type: ['Solid', 'Split'] | |
enum proctor_mold_six_types: ['(Solid)', '(Split)'] | |
enum proctor_hammer_weight: ['5.5lb', '10lb'] | |
enum capping_mold_size: ['2x4', '4x8', '6x12'] | |
enum saw_type: ['Chop', 'Lapidary', 'Tile', 'Wet'] | |
enum penetrometer_type: ['Cone', 'Acme', 'Concrete', 'Soil'] | |
# Items index "Item Type" filter | |
scope :in_type, -> (type_name) { joins(:item_type).where(types: { name: type_name }) } | |
# Items index "In Service Only" filter | |
scope :in_service, -> { joins(:last_service_event).where(service_events: { status: ServiceEvent.statuses[:in_service] }) } | |
# Campus index filter | |
scope :at_campus, -> (campus_name) { joins(:campus).where(campuses: { name: campus_name }) } | |
# Fix this scope to filter calibrations due soon | |
# scope :calibration_due_soon, -> { joins(:last_calibration_event).where(calibration_events: { :date_performed... }) } | |
# Items index search query | |
scope :search, -> (query) { joins(:item_type, location: :campus) | |
.where("cast(items.id as text) ILIKE ? | |
OR serial_number ILIKE ? | |
OR manufacturer ILIKE ? | |
OR model ILIKE ? | |
OR items.notes ILIKE ? | |
OR item_types.name ILIKE ? | |
OR locations.name ILIKE ? | |
OR campuses.name ILIKE ?", | |
"#{query}", | |
"#{query}%", | |
"#{query}%", | |
"#{query}%", | |
"%#{query}%", | |
"%#{query}%", | |
"%#{query}%", | |
"%#{query}%" | |
) | |
} | |
# Conversions for purchase_cost to display as currency | |
# (had to work around number_field limitations) | |
def purchase_cost | |
purchase_cost_in_cents.to_f / 100 | |
end | |
def purchase_cost=(value) | |
value = value.to_f * 100 | |
self.purchase_cost_in_cents = value | |
end | |
# When location_id of item is changed via the edit form, store | |
# location change info so that a location_change record can be created | |
def store_location_change | |
location_changes.create(location_id: location_id, date_of_change: DateTime.now.to_date) | |
end | |
# Check for presence of item_type variables for helper in the view | |
def has_item_type_variables | |
if | |
self.sieve_type? || | |
self.sieve_diameter? || | |
self.flask_type? || | |
self.volume? || | |
self.caliper_type? || | |
self.caliper_size? || | |
self.gauge_type? || | |
self.thermometer_type? || | |
self.scale_resolution? || | |
self.scale_range? || | |
self.groove_tool_type? || | |
self.operation_type? || | |
self.marshall_compaction_pedestal_number? || | |
self.proctor_mold_type? || | |
self.proctor_mold_six_type? || | |
self.proctor_hammer_weight? || | |
self.capping_mold_size? || | |
self.saw_type? || | |
self.penetrometer_type? | |
true | |
else | |
false | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment