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
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
- #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 Models::EventPublishable
Instance Attribute Details
#custom_slug ⇒ Object (readonly)
53 |
# File 'app/models/floor_plan_display.rb', line 53 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)
54 |
# File 'app/models/floor_plan_display.rb', line 54 validates :enabled_buttons, presence: true |
#name ⇒ Object (readonly)
Validations
Validations:
51 |
# File 'app/models/floor_plan_display.rb', line 51 validates :name, presence: true |
#state ⇒ Object (readonly)
52 |
# File 'app/models/floor_plan_display.rb', line 52 validates :state, presence: true |
Class Method Details
.archived ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are archived. Active Record Scope
82 |
# File 'app/models/floor_plan_display.rb', line 82 scope :archived, -> { where(state: 'archived') } |
.draft ⇒ ActiveRecord::Relation<FloorPlanDisplay>
A relation of FloorPlanDisplays that are draft. Active Record Scope
81 |
# File 'app/models/floor_plan_display.rb', line 81 scope :draft, -> { where(state: 'draft') } |
.filter_value_options ⇒ Object
232 233 234 235 236 |
# File 'app/models/floor_plan_display.rb', line 232 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
206 207 208 209 |
# File 'app/models/floor_plan_display.rb', line 206 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
80 |
# File 'app/models/floor_plan_display.rb', line 80 scope :published, -> { where(state: 'published') } |
.ransackable_scopes(_auth_object = nil) ⇒ Object
Note: all_tags method provided by Models::Taggable concern
240 241 242 |
# File 'app/models/floor_plan_display.rb', line 240 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
84 85 86 87 |
# File 'app/models/floor_plan_display.rb', line 84 scope :room_types_include, ->(*room_type_ids) { ids = room_type_ids.flatten.map(&:presence).compact.uniq.map(&:to_s) where('room_types && ARRAY[?]::varchar[]', ids) } |
Instance Method Details
#breadcrumbs_hash ⇒ Object
Build breadcrumb hash like Articles/Posts do
175 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 |
# File 'app/models/floor_plan_display.rb', line 175 def bc = [] # Only use the first breadcrumb if multiple exist = ( || []).first return bc unless .present? 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
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'app/models/floor_plan_display.rb', line 151 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
137 138 139 |
# File 'app/models/floor_plan_display.rb', line 137 def () .include?() end |
#customer ⇒ Customer
Associations
40 |
# File 'app/models/floor_plan_display.rb', line 40 belongs_to :customer, optional: true |
#digital_assets ⇒ ActiveRecord::Relation<DigitalAsset>
44 |
# File 'app/models/floor_plan_display.rb', line 44 has_many :digital_assets, through: :floor_plan_display_digital_assets |
#disable_button(button_name) ⇒ Object
147 148 149 |
# File 'app/models/floor_plan_display.rb', line 147 def () self. = - [] end |
#enable_button(button_name) ⇒ Object
141 142 143 144 145 |
# File 'app/models/floor_plan_display.rb', line 141 def () return false unless AVAILABLE_BUTTONS.include?() self. = ( + []).uniq end |
#floor_plan_display_digital_assets ⇒ ActiveRecord::Relation<FloorPlanDisplayDigitalAsset>
43 |
# File 'app/models/floor_plan_display.rb', line 43 has_many :floor_plan_display_digital_assets, dependent: :destroy |
#floor_plan_display_room_configurations ⇒ ActiveRecord::Relation<FloorPlanDisplayRoomConfiguration>
41 |
# File 'app/models/floor_plan_display.rb', line 41 has_many :floor_plan_display_room_configurations, dependent: :destroy |
#main_image ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'app/models/floor_plan_display.rb', line 104 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
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'app/models/floor_plan_display.rb', line 211 def purge_edge_cache(include_indirect_associations: false, extra_urls: []) 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>
42 |
# File 'app/models/floor_plan_display.rb', line 42 has_many :room_configurations, through: :floor_plan_display_room_configurations |
#site_maps ⇒ ActiveRecord::Relation<SiteMap>
45 |
# File 'app/models/floor_plan_display.rb', line 45 has_many :site_maps, as: :resource, dependent: :destroy |
#to_param ⇒ Object
121 122 123 |
# File 'app/models/floor_plan_display.rb', line 121 def to_param custom_slug end |
#total_cost_to_operate ⇒ Object
Methods
90 91 92 93 94 95 96 |
# File 'app/models/floor_plan_display.rb', line 90 def total_cost_to_operate if association(:floor_plan_display_room_configurations).loaded? floor_plan_display_room_configurations.map { |rc| rc.cost_to_operate.to_f }.sum 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
99 100 101 102 |
# File 'app/models/floor_plan_display.rb', line 99 def total_flooring_area_sqft # assumes room_configurations and their nested associations are eager loaded by caller room_configurations.map { |rc| rc.respond_to?(:installation_sqft) ? rc.installation_sqft.to_f : 0.0 }.sum.round end |