Class: FloorPlanDisplay
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- FloorPlanDisplay
- Includes:
- Models::Auditable, Models::Taggable
- Defined in:
- app/models/floor_plan_display.rb
Overview
== Schema Information
Table name: floor_plan_displays
Database name: primary
id :bigint not null, primary key
breadcrumbs :string default([]), not null, is an Array
custom_slug :string
description :text
enabled_buttons :jsonb
filter_value :string
name :string
room_types :string default([]), not null, is an Array
seo_description :text
seo_title :string
state :string
created_at :datetime not null
updated_at :datetime not null
creator_id :integer
customer_id :integer
updater_id :integer
Indexes
index_floor_plan_displays_on_creator_id (creator_id)
index_floor_plan_displays_on_custom_slug (custom_slug) UNIQUE
index_floor_plan_displays_on_customer_id (customer_id)
index_floor_plan_displays_on_enabled_buttons (enabled_buttons) USING gin
index_floor_plan_displays_on_updater_id (updater_id)
Foreign Keys
fk_rails_... (customer_id => parties.id)
Constant Summary collapse
- AVAILABLE_BUTTONS =
Button management methods
%w[ button_design_room button_floor_heating_quote button_customize_floor_plan button_snow_melting_quote button_floor_heating button_snow_melting button_roof_gutter_deicing button_pipe_freeze_protection ].freeze
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
Constants included from Schedulable
Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
- #custom_slug ⇒ Object readonly
- #enabled_buttons ⇒ Object readonly
-
#name ⇒ Object
readonly
Validations.
- #state ⇒ Object readonly
Belongs to collapse
-
#customer ⇒ Customer
Associations.
Methods included from Models::Auditable
Has many collapse
- #digital_assets ⇒ ActiveRecord::Relation<DigitalAsset>
- #floor_plan_display_digital_assets ⇒ ActiveRecord::Relation<FloorPlanDisplayDigitalAsset>
- #floor_plan_display_room_configurations ⇒ ActiveRecord::Relation<FloorPlanDisplayRoomConfiguration>
- #room_configurations ⇒ ActiveRecord::Relation<RoomConfiguration>
- #site_maps ⇒ ActiveRecord::Relation<SiteMap>
Methods included from Models::Taggable
Class Method Summary collapse
-
.archived ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are archived.
-
.draft ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are draft.
- .filter_value_options ⇒ Object
-
.flush_edge_cache ⇒ Object
Class methods.
-
.published ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are published.
-
.ransackable_scopes(_auth_object = nil) ⇒ Object
NOTE: all_tags method provided by Models::Taggable concern.
-
.room_types_include ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are room types include.
Instance Method Summary collapse
-
#breadcrumbs_hash ⇒ Object
Build breadcrumb hash like Articles/Posts do.
- #button_display_name(button_name) ⇒ Object
- #button_enabled?(button_name) ⇒ Boolean
- #disable_button(button_name) ⇒ Object
- #enable_button(button_name) ⇒ Object
- #main_image ⇒ Object
-
#purge_edge_cache(include_indirect_associations: false, extra_urls: []) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument.
- #to_param ⇒ Object
-
#total_cost_to_operate ⇒ Object
Methods.
-
#total_flooring_area_sqft ⇒ Object
Sum of installation coverage across linked room configurations.
Methods included from Models::Taggable
#add_tag, all_tags, #has_tag?, normalize_tag_names, not_tagged_with, #remove_tag, #tag_list, #tag_list=, #taggable_type_for_tagging, tagged_with, #tags, #tags=, tags_cloud, tags_exclude, tags_include, with_all_tags, with_any_tags, without_all_tags, without_any_tags
Methods included from Models::Auditable
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransortable_attributes, #to_relation
Methods included from Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Instance Attribute Details
#custom_slug ⇒ Object (readonly)
54 |
# File 'app/models/floor_plan_display.rb', line 54 validates :custom_slug, presence: true, uniqueness: true, format: { with: /\A[a-z0-9-]+\z/, message: 'can only contain lowercase letters, numbers, and hyphens' } |
#enabled_buttons ⇒ Object (readonly)
55 |
# File 'app/models/floor_plan_display.rb', line 55 validates :enabled_buttons, presence: true |
#name ⇒ Object (readonly)
Validations
Validations:
52 |
# File 'app/models/floor_plan_display.rb', line 52 validates :name, presence: true |
#state ⇒ Object (readonly)
53 |
# File 'app/models/floor_plan_display.rb', line 53 validates :state, presence: true |
Class Method Details
.archived ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are archived. Active Record Scope
83 |
# File 'app/models/floor_plan_display.rb', line 83 scope :archived, -> { where(state: 'archived') } |
.draft ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are draft. Active Record Scope
82 |
# File 'app/models/floor_plan_display.rb', line 82 scope :draft, -> { where(state: 'draft') } |
.filter_value_options ⇒ Object
233 234 235 236 237 |
# File 'app/models/floor_plan_display.rb', line 233 def self. ['G Shaped - Peninsula', 'L Shaped', 'U Shaped', 'Single Wall or Straight Kitchen', 'Corridor or Gallery Kitchen', 'Island Kitchen', 'Small', 'Medium', 'Large', '1-49 sq.ft.', '50-99 sq.ft.', '100-149 sq.ft.', '150-199 sq.ft.', '200+ sq.ft.', 'Shower Only', 'Shower + Bench'] end |
.flush_edge_cache ⇒ Object
Class methods
207 208 209 210 |
# File 'app/models/floor_plan_display.rb', line 207 def self.flush_edge_cache # Implementation for edge cache flushing # This would typically call a cache service end |
.published ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are published. Active Record Scope
81 |
# File 'app/models/floor_plan_display.rb', line 81 scope :published, -> { where(state: 'published') } |
.ransackable_scopes(_auth_object = nil) ⇒ Object
NOTE: all_tags method provided by Models::Taggable concern
241 242 243 |
# File 'app/models/floor_plan_display.rb', line 241 def self.ransackable_scopes(_auth_object = nil) %i[tags_include room_types_include] end |
.room_types_include ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are room types include. Active Record Scope
85 86 87 88 |
# File 'app/models/floor_plan_display.rb', line 85 scope :room_types_include, ->(*room_type_ids) { ids = room_type_ids.flatten.filter_map(&:presence).uniq.map(&:to_s) where('room_types && ARRAY[?]::varchar[]', ids) } |
Instance Method Details
#breadcrumbs_hash ⇒ Object
Build breadcrumb hash like Articles/Posts do
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'app/models/floor_plan_display.rb', line 176 def bc = [] # Only use the first breadcrumb if multiple exist = ( || []).first return bc if .blank? begin parts = .split('@') path_url = nil path_name = nil if parts.size == 2 path_name, path_url = parts else path_url = path_name = .split('/').last.to_s.scan(/\w+/).join(' ').humanize end bc << { url: "/#{I18n.locale}/#{path_url}".squeeze('/'), name: path_name } rescue StandardError Rails.logger.error 'Error in FloorPlanDisplay#breadcrumbs_hash path formatting' end # Append "Floor Plans" linking to the public index as the last crumb begin floor_plans_url = Rails.application.routes.url_helpers.floor_plans_path(locale: I18n.locale) bc << { name: 'Floor Plans', url: floor_plans_url } rescue StandardError # ignore if routes not available end bc end |
#button_display_name(button_name) ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'app/models/floor_plan_display.rb', line 152 def () case when 'button_design_room' 'Design Room' when 'button_floor_heating_quote' 'Floor Heating Quote' when 'button_customize_floor_plan' 'Customize Floor Plan' when 'button_snow_melting_quote' 'Snow Melting Quote' when 'button_floor_heating' 'Floor Heating' when 'button_snow_melting' 'Snow Melting' when 'button_roof_gutter_deicing' 'Roof Gutter Deicing' when 'button_pipe_freeze_protection' 'Pipe Freeze Protection' else .humanize end end |
#button_enabled?(button_name) ⇒ Boolean
138 139 140 |
# File 'app/models/floor_plan_display.rb', line 138 def () .include?() end |
#customer ⇒ Customer
Associations
41 |
# File 'app/models/floor_plan_display.rb', line 41 belongs_to :customer, optional: true |
#digital_assets ⇒ ActiveRecord::Relation<DigitalAsset>
45 |
# File 'app/models/floor_plan_display.rb', line 45 has_many :digital_assets, through: :floor_plan_display_digital_assets |
#disable_button(button_name) ⇒ Object
148 149 150 |
# File 'app/models/floor_plan_display.rb', line 148 def () self. = - [] end |
#enable_button(button_name) ⇒ Object
142 143 144 145 146 |
# File 'app/models/floor_plan_display.rb', line 142 def () return false unless AVAILABLE_BUTTONS.include?() self. = ( + []).uniq end |
#floor_plan_display_digital_assets ⇒ ActiveRecord::Relation<FloorPlanDisplayDigitalAsset>
44 |
# File 'app/models/floor_plan_display.rb', line 44 has_many :floor_plan_display_digital_assets, dependent: :destroy |
#floor_plan_display_room_configurations ⇒ ActiveRecord::Relation<FloorPlanDisplayRoomConfiguration>
42 |
# File 'app/models/floor_plan_display.rb', line 42 has_many :floor_plan_display_room_configurations, dependent: :destroy |
#main_image ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'app/models/floor_plan_display.rb', line 105 def main_image # prefer using preloaded associations to avoid N+1 preloaded = floor_plan_display_digital_assets .select { |fpda| fpda.room_configuration_id.nil? && fpda.digital_asset&.type == 'Image' } .min_by(&:position) return preloaded.digital_asset if preloaded # fallback query when not preloaded floor_plan_display_digital_assets .joins(:digital_asset) .where(room_configuration_id: nil) .where(digital_assets: { type: 'Image' }) .order(:position) .first &.digital_asset end |
#purge_edge_cache(include_indirect_associations: false, extra_urls: []) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'app/models/floor_plan_display.rb', line 212 def purge_edge_cache(include_indirect_associations: false, extra_urls: []) # rubocop:disable Lint/UnusedMethodArgument urls = site_maps.map(&:url) + extra_urls # Also purge index and relevant room-type listing pages begin uh = Rails.application.routes.url_helpers urls << uh.floor_plans_path(locale: I18n.locale) Array(room_types).each do |rt_id| rt = RoomType.find_by(id: rt_id.to_i) next unless rt slug = rt.seo_key.presence || rt.name.parameterize urls << uh.floor_plans_by_room_type_path(slug, locale: I18n.locale) end rescue StandardError # Ignore routing issues in purge helper end urls = urls.compact.uniq EdgeCacheWorker.perform_async('urls' => urls) if urls.present? urls end |
#room_configurations ⇒ ActiveRecord::Relation<RoomConfiguration>
43 |
# File 'app/models/floor_plan_display.rb', line 43 has_many :room_configurations, through: :floor_plan_display_room_configurations |
#site_maps ⇒ ActiveRecord::Relation<SiteMap>
46 |
# File 'app/models/floor_plan_display.rb', line 46 has_many :site_maps, as: :resource, dependent: :destroy |
#to_param ⇒ Object
122 123 124 |
# File 'app/models/floor_plan_display.rb', line 122 def to_param custom_slug end |
#total_cost_to_operate ⇒ Object
Methods
91 92 93 94 95 96 97 |
# File 'app/models/floor_plan_display.rb', line 91 def total_cost_to_operate if association(:floor_plan_display_room_configurations).loaded? floor_plan_display_room_configurations.sum { |rc| rc.cost_to_operate.to_f } else floor_plan_display_room_configurations.sum(:cost_to_operate) end end |
#total_flooring_area_sqft ⇒ Object
Sum of installation coverage across linked room configurations
100 101 102 103 |
# File 'app/models/floor_plan_display.rb', line 100 def total_flooring_area_sqft # assumes room_configurations and their nested associations are eager loaded by caller room_configurations.sum { |rc| rc.respond_to?(:installation_sqft) ? rc.installation_sqft.to_f : 0.0 }.round end |