lib/partitioned/partitioned_base.rb in partitioned-1.1.3 vs lib/partitioned/partitioned_base.rb in partitioned-1.1.5

- old
+ new

@@ -101,41 +101,48 @@ # Return an instance of this partition table's sql_adapter (used by the partition manage to # create SQL statements) # # @return [{SqlAdapter}] the object used to create sql statements for this partitioned model def self.sql_adapter - @sql_adapter = self::SqlAdapter.new(self) unless @sql_adapter.present? + @sql_adapter ||= connection.partitioned_sql_adapter(self) return @sql_adapter end + + def self.arel_table_from_key_values(partition_key_values, as = nil) + @arel_tables ||= {} + new_arel_table = @arel_tables[[partition_key_values, as]] + + unless new_arel_table + arel_engine_hash = {:engine => self.arel_engine, :as => as} + new_arel_table = Arel::Table.new(self.partition_table_name(*partition_key_values), arel_engine_hash) + @arel_tables[[partition_key_values, as]] = new_arel_table + end + return new_arel_table + end + # # In activerecord 3.0 we need to supply an Arel::Table for the key value(s) used # to determine the specific child table to access. # # @param [Hash] values key/value pairs for all attributes # @param [String] as (nil) the name of the table associated with this Arel::Table # @return [Arel::Table] the generated Arel::Table def self.dynamic_arel_table(values, as = nil) - @arel_tables ||= {} key_values = self.partition_key_values(values) - new_arel_table = @arel_tables[key_values] - arel_engine_hash = {:engine => self.arel_engine} - arel_engine_hash[:as] = as unless as.blank? - new_arel_table = Arel::Table.new(self.partition_table_name(*key_values), arel_engine_hash) - return new_arel_table + return arel_table_from_key_values(key_values, as) end # # Used by our active record hacks to supply an Arel::Table given this active record's # current attributes. # # @param [String] as (nil) the name of the table associated with the Arel::Table # @return [Arel::Table] the generated Arel::Table def dynamic_arel_table(as = nil) - symbolized_attributes = attributes.symbolize_keys - key_values = Hash[*self.class.partition_keys.map{|name| [name,symbolized_attributes[name]]}.flatten] - return self.class.dynamic_arel_table(key_values, as) + key_values = self.class.partition_key_values(attributes) + return self.class.arel_table_from_key_values(key_values, as) end # # This scoping is used to target the # active record find() to a specific child table and alias it to the name of the @@ -147,14 +154,13 @@ # # where KEY is the key value(s) used as the check constraint on Foo's table. # # @param [*Array<Object>] partition_field the field values to partition on # @return [Hash] the scoping - def self.from_partition(*partition_field) - table_alias_name = partition_table_alias_name(*partition_field) - from("#{partition_table_name(*partition_field)} AS #{table_alias_name}"). - tap{|relation| relation.table.table_alias = table_alias_name} + def self.from_partition(*partition_key_values) + table_alias_name = partition_table_alias_name(*partition_key_values) + return ActiveRecord::Relation.new(self, self.arel_table_from_key_values(partition_key_values, table_alias_name)) end # # This scope is used to target the # active record find() to a specific child table. Is probably best used in advanced @@ -175,14 +181,12 @@ # which fails because table foos is not referenced. using the form #from_partition # is almost always the correct thing when using activerecord. # # @param [*Array<Object>] partition_field the field values to partition on # @return [Hash] the scoping - def self.from_partition_without_alias(*partition_field) - table_alias_name = partition_table_name(*partition_field) - from(table_alias_name). - tap{|relation| relation.table.table_alias = table_alias_name} + def self.from_partition_without_alias(*partition_key_values) + return ActiveRecord::Relation.new(self, self.arel_table_from_key_values(partition_key_values, nil)) end # # Return a object used to read configurator information. # @@ -303,10 +307,10 @@ # # A reasonable alias for this table # partition.table_alias_name lambda {|model, *partition_key_values| - return model.configurator.parent_table_name(*partition_key_values).gsub('.', '_') + return model.table_name } # # The name of the child table without a schema name or prefix. this is used to # build child table names for multi-level partitions.