Class: ActiveWarehouse::Fact
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- ActiveWarehouse::Fact
- Defined in:
- lib/active_warehouse/fact.rb
Overview
Facts represent business measures. A row in a fact table corresponds to set of measurements in a particular granularity along with the foreign keys connecting the fact to various dimensions. All measurements in a fact table must be at the same grain.
Class Attribute Summary collapse
-
.aggregate_fields ⇒ Object
Get a list of all aggregate fields.
-
.calculated_field_options ⇒ Object
Hash of calculated field options, where the key is the field name and the value is the Hash of options for that calculated field.
-
.calculated_fields ⇒ Object
Get a list of all calculated fields.
-
.dimension_relationships ⇒ Object
Array of belongs_to
Reflection
instances that represent the dimensions for this fact.
Class Method Summary collapse
-
.aggregate_field_for_name(name) ⇒ Object
Get the AggregateField instance for the specified name.
-
.calculated_field(field, options = {}, &block) ⇒ Object
Define a calculated field *
field
: The field name *options
: An options hash. -
.calculated_field_for_name(name) ⇒ Object
Get the CalculatedField instance for the specified name.
-
.class_for_name(name) ⇒ Object
Get the class for the specified fact name.
-
.class_name(name) ⇒ Object
Get the class name for the specified fact name.
-
.define_aggregate(field, options = {}) ⇒ Object
(also: aggregate)
Define an aggregate.
-
.define_prejoin(field) ⇒ Object
(also: prejoin)
Define prejoined fields from a dimension of the fact.
-
.dimension(association_id, options = {}) ⇒ Object
Acts as an alias for
belongs_to
, yet marks this relationship as a dimension. -
.dimension_class(dimension_name) ⇒ Object
Returns the dimension class, given a dimension name from this fact.
-
.dimensions ⇒ Object
Return a list of dimensions for this fact.
-
.field_for_name(name) ⇒ Object
Get the field instance for the specified name.
-
.foreign_key_for(dimension_name) ⇒ Object
Return the foreign key that the fact uses to relate back to the specified dimension.
-
.has_semiadditive_fact? ⇒ Boolean
Returns true if this fact has at least one fact that is semiadditive, or false.
-
.last_modified ⇒ Object
Get the time when the fact source file was last modified.
- .populate ⇒ Object
- .prejoin_fact ⇒ Object
-
.prejoined_fields ⇒ Object
Get the hash of all prejoined fields.
-
.prejoined_table_name ⇒ Object
The table name to use for the prejoined fact table.
-
.slowly_changes_over_class(dimension_name) ⇒ Object
returns the Class for the dimension which the specified
dimension_name
is slowly changing over. -
.slowly_changes_over_name(dimension_name) ⇒ Object
returns the dimension name (as specified in the dimension macro) which the specified
dimension_name
is slowly changing over. -
.table_name ⇒ Object
Get the table name.
-
.to_fact(fact_name) ⇒ Object
Get the fact class for the specified value.
Class Attribute Details
.aggregate_fields ⇒ Object
Get a list of all aggregate fields
11 12 13 |
# File 'lib/active_warehouse/fact.rb', line 11 def aggregate_fields @aggregate_fields end |
.calculated_field_options ⇒ Object
Hash of calculated field options, where the key is the field name and the value is the Hash of options for that calculated field.
18 19 20 |
# File 'lib/active_warehouse/fact.rb', line 18 def @calculated_field_options end |
.calculated_fields ⇒ Object
Get a list of all calculated fields
14 15 16 |
# File 'lib/active_warehouse/fact.rb', line 14 def calculated_fields @calculated_fields end |
.dimension_relationships ⇒ Object
Array of belongs_to Reflection
instances that represent the dimensions for this fact.
22 23 24 |
# File 'lib/active_warehouse/fact.rb', line 22 def dimension_relationships @dimension_relationships end |
Class Method Details
.aggregate_field_for_name(name) ⇒ Object
Get the AggregateField instance for the specified name.
174 175 176 |
# File 'lib/active_warehouse/fact.rb', line 174 def aggregate_field_for_name(name) aggregate_fields.find {|f| f.name.to_s == name.to_s} end |
.calculated_field(field, options = {}, &block) ⇒ Object
Define a calculated field
-
field
: The field name -
options
: An options hash
This method takes a block which will be passed the current aggregate record.
Example: calculated_field (:gross_margin) { |r| r.gross_profit_dollar_amount / r.sales_dollar_amount}
145 146 147 |
# File 'lib/active_warehouse/fact.rb', line 145 def calculated_field(field, ={}, &block) calculated_fields << CalculatedField.new(self, field, [:type], , &block) end |
.calculated_field_for_name(name) ⇒ Object
Get the CalculatedField instance for the specified name
164 165 166 |
# File 'lib/active_warehouse/fact.rb', line 164 def calculated_field_for_name(name) calculated_fields.find {|f| f.name.to_s == name.to_s} end |
.class_for_name(name) ⇒ Object
Get the class for the specified fact name
97 98 99 |
# File 'lib/active_warehouse/fact.rb', line 97 def class_for_name(name) class_name(name).constantize end |
.class_name(name) ⇒ Object
Get the class name for the specified fact name
90 91 92 93 94 |
# File 'lib/active_warehouse/fact.rb', line 90 def class_name(name) fact_name = name.to_s fact_name = "#{fact_name}_facts" unless fact_name =~ /_fact[s?]$/ fact_name.classify end |
.define_aggregate(field, options = {}) ⇒ Object Also known as: aggregate
Define an aggregate. Also aliased from aggregate()
-
field
: The field name -
options
: A hash of options for the aggregate
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/active_warehouse/fact.rb', line 117 def define_aggregate(field, ={}) if columns_hash[field.to_s].nil? raise ArgumentError, "Field #{field} does not exist in table #{table_name}" end [:type] ||= :sum aggregate_field = AggregateField.new(self, columns_hash[field.to_s], [:type], ) aggregate_fields << aggregate_field end |
.define_prejoin(field) ⇒ Object Also known as: prejoin
Define prejoined fields from a dimension of the fact. Also aliased from prejoin()
-
field
: A hash with the key of dimension and an array
of attributes from the dimension as value
133 134 135 |
# File 'lib/active_warehouse/fact.rb', line 133 def define_prejoin(field) prejoined_fields.merge!(field) end |
.dimension(association_id, options = {}) ⇒ Object
Acts as an alias for belongs_to
, yet marks this relationship as a dimension. You must call dimension
instead of belongs_to
. Accepts same options as belongs_to
.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/active_warehouse/fact.rb', line 27 def dimension(association_id, = {}) [:class_name] ||= "#{association_id}Dimension".classify [:foreign_key] ||= "#{association_id}_id" slowly_changing_over = .delete(:slowly_changing) belongs_to association_id, dimension_relationship = reflections[association_id] if slowly_changing_over if !dimensions.include?(slowly_changing_over) raise "No dimension specified with name '#{slowly_changing_over}' in fact '#{self.name}', specify it first with dimension macro" end dimension_relationship.slowly_changing_over = dimension_relationships[slowly_changing_over] end dimension_relationships[association_id] = dimension_relationship end |
.dimension_class(dimension_name) ⇒ Object
Returns the dimension class, given a dimension name from this fact. Must appear as a registered dimension relationship.
73 74 75 |
# File 'lib/active_warehouse/fact.rb', line 73 def dimension_class(dimension_name) dimension_relationships[dimension_name.to_sym].class_name.constantize end |
.dimensions ⇒ Object
Return a list of dimensions for this fact.
Example:
sales_fact
date_id
region_id
sales_amount
number_items_sold
Calling SalesFact.dimensions would return the list: [:date, :region]
67 68 69 |
# File 'lib/active_warehouse/fact.rb', line 67 def dimensions dimension_relationships.collect { |k,v| k } end |
.field_for_name(name) ⇒ Object
Get the field instance for the specified name. Looks in aggregate fields first, then calculated fields
180 181 182 183 184 |
# File 'lib/active_warehouse/fact.rb', line 180 def field_for_name(name) field = aggregate_fields.find {|f| f.name.to_s == name.to_s} field = calculated_fields.find {|f| f.name.to_s == name.to_s} unless field field end |
.foreign_key_for(dimension_name) ⇒ Object
Return the foreign key that the fact uses to relate back to the specified dimension. This is found using the dimension_relationships hash.
110 111 112 |
# File 'lib/active_warehouse/fact.rb', line 110 def foreign_key_for(dimension_name) dimension_relationships[dimension_name].primary_key_name end |
.has_semiadditive_fact? ⇒ Boolean
Returns true if this fact has at least one fact that is semiadditive, or false
151 152 153 154 155 156 |
# File 'lib/active_warehouse/fact.rb', line 151 def has_semiadditive_fact? aggregate_fields.each do |field| return true if field.is_semiadditive? end return false end |
.last_modified ⇒ Object
Get the time when the fact source file was last modified
78 79 80 |
# File 'lib/active_warehouse/fact.rb', line 78 def last_modified File.new(__FILE__).mtime end |
.populate ⇒ Object
204 205 206 |
# File 'lib/active_warehouse/fact.rb', line 204 def populate prejoin_fact.populate end |
.prejoin_fact ⇒ Object
200 201 202 |
# File 'lib/active_warehouse/fact.rb', line 200 def prejoin_fact @prejoin_fact ||= ActiveWarehouse::PrejoinFact.new(self) end |
.prejoined_fields ⇒ Object
Get the hash of all prejoined fields
192 193 194 |
# File 'lib/active_warehouse/fact.rb', line 192 def prejoined_fields @prejoined_fields ||= {} end |
.prejoined_table_name ⇒ Object
The table name to use for the prejoined fact table
187 188 189 |
# File 'lib/active_warehouse/fact.rb', line 187 def prejoined_table_name "prejoined_#{table_name}" end |
.slowly_changes_over_class(dimension_name) ⇒ Object
returns the Class for the dimension which the specified dimension_name
is slowly changing over
52 53 54 |
# File 'lib/active_warehouse/fact.rb', line 52 def slowly_changes_over_class(dimension_name) dimension_class(slowly_changes_over_name(dimension_name)) end |
.slowly_changes_over_name(dimension_name) ⇒ Object
returns the dimension name (as specified in the dimension macro) which the specified dimension_name
is slowly changing over
46 47 48 |
# File 'lib/active_warehouse/fact.rb', line 46 def slowly_changes_over_name(dimension_name) dimension_relationships[dimension_name].slowly_changing_over.name end |
.table_name ⇒ Object
Get the table name. The fact table name is pluralized
83 84 85 86 87 |
# File 'lib/active_warehouse/fact.rb', line 83 def table_name name = self.name.demodulize.underscore.pluralize set_table_name(name) name end |
.to_fact(fact_name) ⇒ Object
Get the fact class for the specified value. The fact parameter may be a class, String or Symbol.
103 104 105 106 |
# File 'lib/active_warehouse/fact.rb', line 103 def to_fact(fact_name) return fact_name if fact_name.is_a?(Class) and fact_name.superclass == Fact return class_for_name(fact_name) end |