Class: LowCardTables::HasLowCardTable::LowCardAssociationsManager
- Inherits:
-
Object
- Object
- LowCardTables::HasLowCardTable::LowCardAssociationsManager
- Defined in:
- lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb
Overview
The LowCardAssociationsManager is a relatively simple object; it manages the LowCardAssociation objects for a given model class that refers to at least one low-card table. Conceptually, it does little more than maintain an Array of such associations.
(Note that storing this data as an Array is important: part of the contract of the low-card system is that later calls to has_low_card_table
supersede earlier calls, so order is key. Yes, Ruby hashes are ordered in recent Ruby versions…but we support 1.8.7, too.)
Constant Summary collapse
- DEFAULT_COLLAPSING_UPDATE_VALUE =
10_000
Instance Attribute Summary collapse
-
#associations ⇒ Object
readonly
Returns an Array of all LowCardAssociation objects for the given
model_class
.
Instance Method Summary collapse
-
#_low_card_association(name) ⇒ Object
Retrieves the low-card association with the given name.
-
#_low_card_update_collapsed_rows(low_card_model, collapse_map) ⇒ Object
Called when a low-card model has just collapsed rows, presumably because it has had a column removed.
-
#has_low_card_table(association_name, options = { }) ⇒ Object
Called when
has_low_card_table
is declared within the model class; this does all the actual work of setting up the association. -
#initialize(model_class) ⇒ LowCardAssociationsManager
constructor
Creates a new instance.
-
#low_card_column_information_reset!(low_card_model) ⇒ Object
Called when someone has called ::ActiveRecord::Base#reset_column_information on the low-card model in question.
-
#low_card_update_foreign_keys!(model_instance) ⇒ Object
Updates all foreign keys that the given model_instance has to their correct values, given the set of attributes that are associated with that model instance.
-
#low_card_value_collapsing_update_scheme(new_scheme = nil) ⇒ Object
Gets, or sets, the current scheme for updating rows in this table when a low-card table has a column removed and thus needs to have rows collapsed.
-
#maybe_low_card_association(name) ⇒ Object
Just like _low_card_association, but returns nil when an association is not found, rather than raising an error.
Constructor Details
#initialize(model_class) ⇒ LowCardAssociationsManager
Creates a new instance. You should only ever create one instance per model class.
18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 18 def initialize(model_class) if (! superclasses(model_class).include?(::ActiveRecord::Base)) raise ArgumentError, "You must supply an ActiveRecord model, not: #{model_class}" elsif model_class.is_low_card_table? raise ArgumentError, "A low-card table can't itself have low-card associations: #{model_class}" end @model_class = model_class @associations = [ ] @collapsing_update_scheme = :default install_methods! end |
Instance Attribute Details
#associations ⇒ Object (readonly)
Returns an Array of all LowCardAssociation objects for the given model_class
.
15 16 17 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 15 def associations @associations end |
Instance Method Details
#_low_card_association(name) ⇒ Object
Retrieves the low-card association with the given name. Raises LowCardTables::Errors::LowCardAssociationNotFoundError if not found.
57 58 59 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 57 def _low_card_association(name) maybe_low_card_association(name) || (raise LowCardTables::Errors::LowCardAssociationNotFoundError, "There is no low-card association named '#{name}' for #{@model_class.name}; there are associations named: #{@associations.map(&:association_name).sort.join(", ")}.") end |
#_low_card_update_collapsed_rows(low_card_model, collapse_map) ⇒ Object
Called when a low-card model has just collapsed rows, presumably because it has had a column removed. This is responsible for updating each foreign-key column, using the proper low_card_value_collapsing_update_scheme.
105 106 107 108 109 110 111 112 113 114 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 105 def _low_card_update_collapsed_rows(low_card_model, collapse_map) update_scheme = @collapsing_update_scheme update_scheme = DEFAULT_COLLAPSING_UPDATE_VALUE if update_scheme == :default @associations.each do |association| if association.low_card_class == low_card_model association.update_collapsed_rows(collapse_map, update_scheme) end end end |
#has_low_card_table(association_name, options = { }) ⇒ Object
Called when has_low_card_table
is declared within the model class; this does all the actual work of setting up the association. This removes any previous associations with the same name; again, we have a ‘last caller wins’ policy.
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 35 def has_low_card_table(association_name, = { }) unless association_name.kind_of?(Symbol) || (association_name.kind_of?(String) && association_name.strip.length > 0) raise ArgumentError, "You must supply an association name, not: #{association_name.inspect}" end association_name = association_name.to_s.strip.downcase @associations.delete_if { |a| a.association_name.to_s.strip.downcase == association_name } @associations << LowCardTables::HasLowCardTable::LowCardAssociation.new(@model_class, association_name, ) @model_class._low_card_dynamic_method_manager.sync_methods! end |
#low_card_column_information_reset!(low_card_model) ⇒ Object
Called when someone has called ::ActiveRecord::Base#reset_column_information on the low-card model in question. This simply tells the LowCardDynamicMethodManager to sync the methods on this model class, thus updating the set of delegated methods to match the new columns.
51 52 53 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 51 def low_card_column_information_reset!(low_card_model) @model_class._low_card_dynamic_method_manager.sync_methods! end |
#low_card_update_foreign_keys!(model_instance) ⇒ Object
Updates all foreign keys that the given model_instance has to their correct values, given the set of attributes that are associated with that model instance.
68 69 70 71 72 73 74 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 68 def low_card_update_foreign_keys!(model_instance) ensure_correct_class!(model_instance) @associations.each do |association| association.update_foreign_key!(model_instance) end end |
#low_card_value_collapsing_update_scheme(new_scheme = nil) ⇒ Object
Gets, or sets, the current scheme for updating rows in this table when a low-card table has a column removed and thus needs to have rows collapsed. Passing nil
or no arguments retrieves the current scheme; passing anything else sets it. You can set this to:
- :default
-
Rows will be updated in chunks of
DEFAULT_COLLAPSING_UPDATE_VALUE
rows. - :none
-
Nothing will be done; you are entirely on your own, and will have dangling foreign keys.
- a positive integer
-
Rows will be updated in chunks of this many rows at once.
- something that responds to :call
-
This object will have #call invoked on it when rows need to be updated; it will be passed the map of ‘winners’ to ‘losers’, and is responsible for updating rows any way you want.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 88 def low_card_value_collapsing_update_scheme(new_scheme = nil) if (! new_scheme) @collapsing_update_scheme elsif new_scheme == :default || new_scheme == :none @collapsing_update_scheme = new_scheme elsif new_scheme.kind_of?(Integer) raise ArgumentError, "You must specify an integer >= 1, not #{new_scheme.inspect}" unless new_scheme >= 1 @collapsing_update_scheme = new_scheme elsif new_scheme.respond_to?(:call) @collapsing_update_scheme = new_scheme else raise ArgumentError, "Invalid collapsing update scheme: #{new_scheme.inspect}" end end |
#maybe_low_card_association(name) ⇒ Object
Just like _low_card_association, but returns nil when an association is not found, rather than raising an error.
62 63 64 |
# File 'lib/low_card_tables/has_low_card_table/low_card_associations_manager.rb', line 62 def maybe_low_card_association(name) @associations.detect { |a| a.association_name.to_s.strip.downcase == name.to_s.strip.downcase } end |