constant_table_saver 3.0.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/constant_table_saver.rb +66 -58
- data/lib/constant_table_saver/version.rb +1 -1
- data/test/activerecord_count_queries.rb +14 -19
- data/test/constant_table_saver_test.rb +76 -45
- data/test/test_helper.rb +10 -13
- metadata +64 -84
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 250b25d7f3fefffc880e4f1ed9bd349aaa9ed601
         | 
| 4 | 
            +
              data.tar.gz: bc75e2890206f99c0b0bdd049921afca4a55b492
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 7d580056718eac74024e54d0cca28c0219551b9407e6d2540fa753117fd4c8e41d77c99180c009197c7a3e26432a2efaa05894c3a3d4c5de62a5717708be1237
         | 
| 7 | 
            +
              data.tar.gz: baebaf8845f8ca7de92ea243bca01e5e69624d79f293b6b9415e80db9da39c2acbb54d9acf03baf700e2933a40bca563eabcf14de5f9eccd00f3c2aacf98a1a1
         | 
    
        data/lib/constant_table_saver.rb
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            require 'active_record/fixtures' # so we can hook it & reset our cache afterwards
         | 
| 2 | 
            +
            require 'active_support/core_ext/object/to_param'
         | 
| 2 3 |  | 
| 3 4 | 
             
            module ConstantTableSaver
         | 
| 4 5 | 
             
              module BaseMethods
         | 
| @@ -7,16 +8,15 @@ module ConstantTableSaver | |
| 7 8 | 
             
                  class_attribute :constant_table_options, :instance_writer => false
         | 
| 8 9 | 
             
                  self.constant_table_options = options
         | 
| 9 10 |  | 
| 10 | 
            -
                  if ActiveRecord::VERSION::MAJOR  | 
| 11 | 
            -
                    require 'active_support/core_ext/object/to_param'
         | 
| 11 | 
            +
                  if ActiveRecord::VERSION::MAJOR == 3
         | 
| 12 12 | 
             
                    extend ActiveRecord3ClassMethods
         | 
| 13 13 | 
             
                  else
         | 
| 14 | 
            -
                    extend  | 
| 14 | 
            +
                    extend ActiveRecord4ClassMethods
         | 
| 15 15 | 
             
                  end
         | 
| 16 16 | 
             
                  extend ClassMethods
         | 
| 17 17 | 
             
                  extend NameClassMethods if constant_table_options[:name]
         | 
| 18 18 |  | 
| 19 | 
            -
                  klass = defined?( | 
| 19 | 
            +
                  klass = defined?(ActiveRecord::FixtureSet) ? ActiveRecord::FixtureSet : ActiveRecord::Fixtures
         | 
| 20 20 | 
             
                  class <<klass
         | 
| 21 21 | 
             
                    # normally, create_fixtures method gets called exactly once - but unfortunately, it
         | 
| 22 22 | 
             
                    # loads the class and does a #respond_to?, which causes us to load and cache before
         | 
| @@ -45,7 +45,55 @@ module ConstantTableSaver | |
| 45 45 | 
             
                # plugin on if the table isn't really constant!
         | 
| 46 46 | 
             
                def reset_constant_record_cache!
         | 
| 47 47 | 
             
                  @constant_record_methods.each {|method_id| (class << self; self; end;).send(:remove_method, method_id)} if @constant_record_methods
         | 
| 48 | 
            -
                  @cached_records = @cached_records_by_id = @constant_record_methods = @cached_blank_scope = nil
         | 
| 48 | 
            +
                  @cached_records = @cached_records_by_id = @constant_record_methods = @cached_blank_scope = @find_by_sql = nil
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              module ActiveRecord4ClassMethods
         | 
| 53 | 
            +
                def find_by_sql(sql, binds = [])
         | 
| 54 | 
            +
                  @find_by_sql ||= {}
         | 
| 55 | 
            +
                  @find_by_sql[:all]   ||= all.to_sql
         | 
| 56 | 
            +
                  @find_by_sql[:id]    ||= relation.where(relation.table[primary_key].eq(connection.substitute_at(columns_hash[primary_key], 1))).limit(1).to_sql
         | 
| 57 | 
            +
                  @find_by_sql[:oldid] ||= relation.where(relation.table[primary_key].eq(connection.substitute_at(columns_hash[primary_key], 1))).
         | 
| 58 | 
            +
                                                     order(relation.table[primary_key].asc).limit(1).to_sql # used by 4.0
         | 
| 59 | 
            +
                  @find_by_sql[:first] ||= relation.order(relation.table[primary_key].asc).limit(1).to_sql
         | 
| 60 | 
            +
                  @find_by_sql[:last]  ||= relation.order(relation.table[primary_key].desc).limit(1).to_sql
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  _sql = sanitize_sql(sql)
         | 
| 63 | 
            +
                  _sql = _sql.to_sql if sql.respond_to?(:to_sql)
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  if binds.empty?
         | 
| 66 | 
            +
                    if _sql == @find_by_sql[:all]
         | 
| 67 | 
            +
                      return @cached_records ||= super(relation.to_sql).each(&:freeze)
         | 
| 68 | 
            +
                    elsif _sql == @find_by_sql[:first]
         | 
| 69 | 
            +
                      return [relation.to_a.first].compact
         | 
| 70 | 
            +
                    elsif _sql == @find_by_sql[:last]
         | 
| 71 | 
            +
                      return [relation.to_a.last].compact
         | 
| 72 | 
            +
                    end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  elsif (_sql == @find_by_sql[:id] || _sql == @find_by_sql[:oldid]) &&
         | 
| 75 | 
            +
                        binds.length == 1 &&
         | 
| 76 | 
            +
                        binds.first.first.is_a?(ActiveRecord::ConnectionAdapters::Column) &&
         | 
| 77 | 
            +
                        binds.first.first.name == primary_key
         | 
| 78 | 
            +
                    @cached_records_by_id ||= relation.to_a.index_by {|record| record.id.to_param}
         | 
| 79 | 
            +
                    return [@cached_records_by_id[binds.first.last.to_param]].compact
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  super
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                def relation
         | 
| 86 | 
            +
                  super.tap do |s|
         | 
| 87 | 
            +
                    class << s
         | 
| 88 | 
            +
                      # we implement find_some here because we'd have to use partial string matching to catch
         | 
| 89 | 
            +
                      # this case in find_by_sql, which would be ugly.  (we do the other cases in find_by_sql
         | 
| 90 | 
            +
                      # because it's simpler & the only place to catch things like association find queries.)
         | 
| 91 | 
            +
                      def find_some(ids)
         | 
| 92 | 
            +
                        return super if @values.present? # special cases such as offset and limit
         | 
| 93 | 
            +
                        ids.collect {|id| find_one(id)}
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
                    end
         | 
| 96 | 
            +
                  end
         | 
| 49 97 | 
             
                end
         | 
| 50 98 | 
             
              end
         | 
| 51 99 |  | 
| @@ -110,23 +158,21 @@ module ConstantTableSaver | |
| 110 158 | 
             
                      # this so we have to shove in the instance variables.
         | 
| 111 159 | 
             
                      #
         | 
| 112 160 | 
             
                      # it will be clear that this was a very problematic ActiveRecord refactoring.
         | 
| 113 | 
            -
                       | 
| 114 | 
            -
                         | 
| 115 | 
            -
                           | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
                        end
         | 
| 122 | 
            -
             | 
| 123 | 
            -
                        def merge(other)
         | 
| 124 | 
            -
                          if belongs_to_record_scope = belongs_to_record_scopes[other.to_sql]
         | 
| 125 | 
            -
                            return belongs_to_record_scope
         | 
| 126 | 
            -
                          end
         | 
| 161 | 
            +
                      def belongs_to_record_scopes
         | 
| 162 | 
            +
                        @belongs_to_record_scopes ||= to_a.each_with_object({}) do |record, results|
         | 
| 163 | 
            +
                          scope_that_belongs_to_will_want = where(table[primary_key].eq(record.id))
         | 
| 164 | 
            +
                          scope_that_belongs_to_will_want.instance_variable_set("@loaded", true)
         | 
| 165 | 
            +
                          scope_that_belongs_to_will_want.instance_variable_set("@records", [record])
         | 
| 166 | 
            +
                          results[scope_that_belongs_to_will_want.to_sql] = scope_that_belongs_to_will_want
         | 
| 167 | 
            +
                        end.freeze
         | 
| 168 | 
            +
                      end
         | 
| 127 169 |  | 
| 128 | 
            -
             | 
| 170 | 
            +
                      def merge(other)
         | 
| 171 | 
            +
                        if belongs_to_record_scope = belongs_to_record_scopes[other.to_sql]
         | 
| 172 | 
            +
                          return belongs_to_record_scope
         | 
| 129 173 | 
             
                        end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                        super other
         | 
| 130 176 | 
             
                      end
         | 
| 131 177 |  | 
| 132 178 | 
             
                    private
         | 
| @@ -141,45 +187,7 @@ module ConstantTableSaver | |
| 141 187 | 
             
                  end
         | 
| 142 188 | 
             
                end
         | 
| 143 189 | 
             
              end
         | 
| 144 | 
            -
              
         | 
| 145 | 
            -
              module ActiveRecord2ClassMethods
         | 
| 146 | 
            -
                def find(*args)
         | 
| 147 | 
            -
                  options = args.last if args.last.is_a?(Hash)
         | 
| 148 | 
            -
                  return super unless options.blank? || options.all? {|k, v| v.nil?}
         | 
| 149 | 
            -
                  scope_options = scope(:find)
         | 
| 150 | 
            -
                  return super unless scope_options.blank? || scope_options.all? {|k, v| v.nil?}
         | 
| 151 | 
            -
             | 
| 152 | 
            -
                  args.pop unless options.nil?
         | 
| 153 190 |  | 
| 154 | 
            -
                  @cached_records ||= super(:all, :order => primary_key).each(&:freeze)
         | 
| 155 | 
            -
                  @cached_records_by_id ||= @cached_records.index_by {|record| record.id.to_param}
         | 
| 156 | 
            -
             | 
| 157 | 
            -
                  case args.first
         | 
| 158 | 
            -
                    when :first then @cached_records.first
         | 
| 159 | 
            -
                    when :last  then @cached_records.last
         | 
| 160 | 
            -
                    when :all   then @cached_records.dup # shallow copy of the array
         | 
| 161 | 
            -
                    else
         | 
| 162 | 
            -
                      expects_array = args.first.kind_of?(Array)
         | 
| 163 | 
            -
                      return args.first if expects_array && args.first.empty?
         | 
| 164 | 
            -
                      ids = expects_array ? args.first : args
         | 
| 165 | 
            -
                      ids = ids.flatten.compact.uniq
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                      case ids.size
         | 
| 168 | 
            -
                        when 0
         | 
| 169 | 
            -
                          raise ::ActiveRecord::RecordNotFound, "Couldn't find #{name} without an ID"
         | 
| 170 | 
            -
                        when 1
         | 
| 171 | 
            -
                          result = @cached_records_by_id[ids.first.to_param] || raise(::ActiveRecord::RecordNotFound, "Couldn't find #{name} with ID=#{ids.first}")
         | 
| 172 | 
            -
                          expects_array ? [result] : result
         | 
| 173 | 
            -
                        else
         | 
| 174 | 
            -
                          ids.collect {|id| @cached_records_by_id[id.to_param]}.tap do |results|
         | 
| 175 | 
            -
                            results.compact!
         | 
| 176 | 
            -
                            raise(::ActiveRecord::RecordNotFound, "Couldn't find all #{name.pluralize} with IDs #{ids.join ','} (found #{results.size} results, but was looking for #{ids.size}") unless results.size == ids.size
         | 
| 177 | 
            -
                          end
         | 
| 178 | 
            -
                      end
         | 
| 179 | 
            -
                  end
         | 
| 180 | 
            -
                end
         | 
| 181 | 
            -
              end
         | 
| 182 | 
            -
              
         | 
| 183 191 | 
             
              module NameClassMethods
         | 
| 184 192 | 
             
                def define_named_record_methods
         | 
| 185 193 | 
             
                  @constant_record_methods = [] # dummy so respond_to? & method_missing don't call us again if reading an attribute causes another method_missing
         | 
| @@ -1,19 +1,6 @@ | |
| 1 | 
            -
            if ActiveRecord::VERSION::MAJOR  | 
| 2 | 
            -
              # proudly stolen from ActiveRecord's test suite, with addition of BEGIN and COMMIT
         | 
| 3 | 
            -
              ActiveRecord::Base.connection.class.class_eval do
         | 
| 4 | 
            -
                IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /SHOW FIELDS/, /^BEGIN$/, /^COMMIT$/]
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                def execute_with_query_record(sql, name = nil, &block)
         | 
| 7 | 
            -
                  $queries_executed ||= []
         | 
| 8 | 
            -
                  $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
         | 
| 9 | 
            -
                  execute_without_query_record(sql, name, &block)
         | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                alias_method_chain :execute, :query_record
         | 
| 13 | 
            -
              end
         | 
| 14 | 
            -
            elsif ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR < 2
         | 
| 1 | 
            +
            if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR < 2
         | 
| 15 2 | 
             
              # this is from 3.1's test suite.  ugly.
         | 
| 16 | 
            -
              class  | 
| 3 | 
            +
              class SQLCounter
         | 
| 17 4 | 
             
                cattr_accessor :ignored_sql
         | 
| 18 5 | 
             
                self.ignored_sql = [/^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/]
         | 
| 19 6 |  | 
| @@ -21,10 +8,14 @@ elsif ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR < 2 | |
| 21 8 | 
             
                # ignored SQL.  This ignored SQL is for Oracle.
         | 
| 22 9 | 
             
                ignored_sql.concat [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im]
         | 
| 23 10 |  | 
| 24 | 
            -
                def  | 
| 11 | 
            +
                def self.clear_log
         | 
| 25 12 | 
             
                  $queries_executed = []
         | 
| 26 13 | 
             
                end
         | 
| 27 14 |  | 
| 15 | 
            +
                def initialize
         | 
| 16 | 
            +
                  $queries_executed.clear
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 28 19 | 
             
                def call(name, start, finish, message_id, values)
         | 
| 29 20 | 
             
                  sql = values[:sql]
         | 
| 30 21 |  | 
| @@ -36,10 +27,10 @@ elsif ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR < 2 | |
| 36 27 | 
             
                  end
         | 
| 37 28 | 
             
                end
         | 
| 38 29 | 
             
              end
         | 
| 39 | 
            -
              ActiveSupport::Notifications.subscribe('sql.active_record',  | 
| 30 | 
            +
              ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
         | 
| 40 31 | 
             
            else
         | 
| 41 32 | 
             
              # this is from 3.2's test suite.  ugly.
         | 
| 42 | 
            -
              class  | 
| 33 | 
            +
              class SQLCounter
         | 
| 43 34 | 
             
                cattr_accessor :ignored_sql
         | 
| 44 35 | 
             
                self.ignored_sql = [/^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/]
         | 
| 45 36 |  | 
| @@ -52,6 +43,10 @@ else | |
| 52 43 |  | 
| 53 44 | 
             
                attr_reader :ignore
         | 
| 54 45 |  | 
| 46 | 
            +
                def self.clear_log
         | 
| 47 | 
            +
                  self.log.clear
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 55 50 | 
             
                def initialize(ignore = self.class.ignored_sql)
         | 
| 56 51 | 
             
                  @ignore   = ignore
         | 
| 57 52 | 
             
                end
         | 
| @@ -66,5 +61,5 @@ else | |
| 66 61 | 
             
                end
         | 
| 67 62 | 
             
              end
         | 
| 68 63 |  | 
| 69 | 
            -
              ActiveSupport::Notifications.subscribe('sql.active_record',  | 
| 64 | 
            +
              ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
         | 
| 70 65 | 
             
            end
         | 
| @@ -9,11 +9,7 @@ class ConstantPie < ActiveRecord::Base | |
| 9 9 | 
             
              set_table_name "pies"
         | 
| 10 10 | 
             
              constant_table
         | 
| 11 11 |  | 
| 12 | 
            -
               | 
| 13 | 
            -
                named_scope :filled_with_unicorn, :conditions => {:filling => 'unicorn'}
         | 
| 14 | 
            -
              else
         | 
| 15 | 
            -
                scope :filled_with_unicorn, :conditions => {:filling => 'unicorn'}
         | 
| 16 | 
            -
              end
         | 
| 12 | 
            +
              scope :filled_with_unicorn, -> { where(:filling => 'unicorn') }
         | 
| 17 13 |  | 
| 18 14 | 
             
              def self.with_unicorn_filling_scope
         | 
| 19 15 | 
             
                with_scope(:find => {:conditions => {:filling => 'unicorn'}}) { yield }
         | 
| @@ -40,32 +36,45 @@ class IngredientForConstantPie < ActiveRecord::Base | |
| 40 36 | 
             
              belongs_to :pie, :class_name => "ConstantPie"
         | 
| 41 37 | 
             
            end
         | 
| 42 38 |  | 
| 43 | 
            -
            class ConstantTableSaverTest <  | 
| 39 | 
            +
            class ConstantTableSaverTest < ActiveSupport::TestCase
         | 
| 44 40 | 
             
              fixtures :all
         | 
| 45 41 |  | 
| 46 | 
            -
              setup | 
| 42 | 
            +
              def setup
         | 
| 47 43 | 
             
                ConstantPie.reset_constant_record_cache!
         | 
| 48 44 | 
             
              end
         | 
| 49 45 |  | 
| 50 | 
            -
               | 
| 51 | 
            -
                 | 
| 46 | 
            +
              def assert_queries(num = 1)
         | 
| 47 | 
            +
                ::SQLCounter.clear_log
         | 
| 48 | 
            +
                yield
         | 
| 49 | 
            +
              ensure
         | 
| 50 | 
            +
                assert_equal num, ::SQLCounter.log.size, "#{::SQLCounter.log.size} instead of #{num} queries were executed.#{::SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{::SQLCounter.log.join("\n")}"}"
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              def assert_no_queries(&block)
         | 
| 54 | 
            +
                assert_queries(0, &block)
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              DEPRECATED_FINDERS = ActiveRecord::VERSION::MAJOR == 3 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0)
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              test "it caches all() results" do
         | 
| 60 | 
            +
                @pies = StandardPie.all.to_a
         | 
| 52 61 | 
             
                assert_queries(1) do
         | 
| 53 | 
            -
                  assert_equal @pies.collect(&:attributes), ConstantPie. | 
| 62 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.all.to_a.collect(&:attributes)
         | 
| 54 63 | 
             
                end
         | 
| 55 64 | 
             
                assert_no_queries do
         | 
| 56 | 
            -
                  assert_equal @pies.collect(&:attributes), ConstantPie. | 
| 65 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.all.to_a.collect(&:attributes)
         | 
| 57 66 | 
             
                end
         | 
| 58 67 | 
             
              end
         | 
| 59 68 |  | 
| 60 | 
            -
              test "it caches all | 
| 61 | 
            -
                @pies = StandardPie.all
         | 
| 69 | 
            +
              test "it caches find(:all) results" do
         | 
| 70 | 
            +
                @pies = StandardPie.find(:all).to_a
         | 
| 62 71 | 
             
                assert_queries(1) do
         | 
| 63 | 
            -
                  assert_equal @pies.collect(&:attributes), ConstantPie.all.collect(&:attributes)
         | 
| 72 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.find(:all).to_a.collect(&:attributes)
         | 
| 64 73 | 
             
                end
         | 
| 65 74 | 
             
                assert_no_queries do
         | 
| 66 | 
            -
                  assert_equal @pies.collect(&:attributes), ConstantPie.all.collect(&:attributes)
         | 
| 75 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.find(:all).to_a.collect(&:attributes)
         | 
| 67 76 | 
             
                end
         | 
| 68 | 
            -
              end
         | 
| 77 | 
            +
              end if DEPRECATED_FINDERS
         | 
| 69 78 |  | 
| 70 79 | 
             
              test "it caches find(id) results" do
         | 
| 71 80 | 
             
                @pie = StandardPie.find(1)
         | 
| @@ -96,7 +105,7 @@ class ConstantTableSaverTest < ActiveRecord::TestCase | |
| 96 105 | 
             
                assert_no_queries do
         | 
| 97 106 | 
             
                  assert_equal @pie.attributes, ConstantPie.find(:first).attributes
         | 
| 98 107 | 
             
                end
         | 
| 99 | 
            -
              end
         | 
| 108 | 
            +
              end if DEPRECATED_FINDERS
         | 
| 100 109 |  | 
| 101 110 | 
             
              test "it caches first() results" do
         | 
| 102 111 | 
             
                @pie = StandardPie.first
         | 
| @@ -116,7 +125,7 @@ class ConstantTableSaverTest < ActiveRecord::TestCase | |
| 116 125 | 
             
                assert_no_queries do
         | 
| 117 126 | 
             
                  assert_equal @pie.attributes, ConstantPie.find(:last).attributes
         | 
| 118 127 | 
             
                end
         | 
| 119 | 
            -
              end
         | 
| 128 | 
            +
              end if DEPRECATED_FINDERS
         | 
| 120 129 |  | 
| 121 130 | 
             
              test "it caches last() results" do
         | 
| 122 131 | 
             
                @pie = StandardPie.last
         | 
| @@ -129,9 +138,9 @@ class ConstantTableSaverTest < ActiveRecord::TestCase | |
| 129 138 | 
             
              end
         | 
| 130 139 |  | 
| 131 140 | 
             
              test "it caches belongs_to association find queries" do
         | 
| 132 | 
            -
                @standard_pie_ingredients = IngredientForStandardPie.all
         | 
| 141 | 
            +
                @standard_pie_ingredients = IngredientForStandardPie.all.to_a
         | 
| 133 142 | 
             
                @standard_pies = @standard_pie_ingredients.collect(&:pie)
         | 
| 134 | 
            -
                @constant_pie_ingredients = IngredientForConstantPie.all
         | 
| 143 | 
            +
                @constant_pie_ingredients = IngredientForConstantPie.all.to_a
         | 
| 135 144 | 
             
                assert_queries(1) do # doesn't need to make 3 queries for 3 pie assocations!
         | 
| 136 145 | 
             
                  assert_equal @standard_pies.collect(&:attributes), @constant_pie_ingredients.collect(&:pie).collect(&:attributes)
         | 
| 137 146 | 
             
                end
         | 
| @@ -141,46 +150,68 @@ class ConstantTableSaverTest < ActiveRecord::TestCase | |
| 141 150 | 
             
              end
         | 
| 142 151 |  | 
| 143 152 | 
             
              test "it isn't affected by scopes active at the time of first load" do
         | 
| 144 | 
            -
                assert_equal 0, ConstantPie.filled_with_unicorn.all.size
         | 
| 145 | 
            -
                assert_equal 0, ConstantPie.with_unicorn_filling_scope { ConstantPie.all.length }
         | 
| 146 | 
            -
                assert_equal StandardPie.all.size, ConstantPie.all.size
         | 
| 153 | 
            +
                assert_equal 0, ConstantPie.filled_with_unicorn.all.to_a.size
         | 
| 154 | 
            +
                assert_equal 0, ConstantPie.with_unicorn_filling_scope { ConstantPie.all.to_a.length } if DEPRECATED_FINDERS
         | 
| 155 | 
            +
                assert_equal StandardPie.all.to_a.size, ConstantPie.all.to_a.size
         | 
| 147 156 | 
             
              end
         | 
| 148 157 |  | 
| 149 158 | 
             
              test "it isn't affected by relational algebra active at the time of first load" do
         | 
| 150 | 
            -
                assert_equal 0, ConstantPie.filled_with_unicorn.all.size
         | 
| 151 | 
            -
                assert_equal 0, ConstantPie.where(:filling => 'unicorn').all.length
         | 
| 152 | 
            -
                assert_equal 2, ConstantPie.where("filling LIKE 'Tasty%'").all.length
         | 
| 153 | 
            -
                assert_equal StandardPie.all.size, ConstantPie.all.size
         | 
| 154 | 
            -
              end | 
| 159 | 
            +
                assert_equal 0, ConstantPie.filled_with_unicorn.all.to_a.size
         | 
| 160 | 
            +
                assert_equal 0, ConstantPie.where(:filling => 'unicorn').all.to_a.length
         | 
| 161 | 
            +
                assert_equal 2, ConstantPie.where("filling LIKE 'Tasty%'").all.to_a.length
         | 
| 162 | 
            +
                assert_equal StandardPie.all.to_a.size, ConstantPie.all.to_a.size
         | 
| 163 | 
            +
              end
         | 
| 155 164 |  | 
| 156 165 | 
             
              test "prevents the returned records from modification" do
         | 
| 157 | 
            -
                @pie = ConstantPie. | 
| 166 | 
            +
                @pie = ConstantPie.first
         | 
| 158 167 | 
             
                assert @pie.frozen?
         | 
| 159 | 
            -
                assert !StandardPie. | 
| 168 | 
            +
                assert !StandardPie.first.frozen?
         | 
| 160 169 | 
             
              end
         | 
| 161 170 |  | 
| 162 171 | 
             
              test "isn't affected by modifying the returned result arrays" do
         | 
| 163 | 
            -
                @pies = ConstantPie.all
         | 
| 172 | 
            +
                @pies = ConstantPie.all.to_a
         | 
| 164 173 | 
             
                @pies.reject! {|pie| pie.filling =~ /Steak/}
         | 
| 165 | 
            -
                assert_equal StandardPie.all.collect(&:attributes), ConstantPie.all.collect(&:attributes)
         | 
| 174 | 
            +
                assert_equal StandardPie.all.to_a.collect(&:attributes), ConstantPie.all.to_a.collect(&:attributes)
         | 
| 175 | 
            +
              end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
              test "it doesn't cache find queries on scopes with options" do
         | 
| 178 | 
            +
                @pies = StandardPie.select("id").all.to_a
         | 
| 179 | 
            +
                @pie = StandardPie.select("id").find(1)
         | 
| 180 | 
            +
                @second_pie = StandardPie.select("id").find(2)
         | 
| 181 | 
            +
                assert_queries(3) do
         | 
| 182 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.select("id").all.collect(&:attributes)
         | 
| 183 | 
            +
                  assert_equal @pie.attributes, ConstantPie.select("id").find(1).attributes
         | 
| 184 | 
            +
                  assert_equal [@pie, @second_pie].collect(&:attributes), ConstantPie.select("id").find([1, 2]).collect(&:attributes)
         | 
| 185 | 
            +
                end
         | 
| 186 | 
            +
                assert_queries(3) do
         | 
| 187 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.select("id").all.collect(&:attributes)
         | 
| 188 | 
            +
                  assert_equal @pie.attributes, ConstantPie.select("id").find(1).attributes
         | 
| 189 | 
            +
                  assert_equal [@pie, @second_pie].collect(&:attributes), ConstantPie.select("id").find([1, 2]).collect(&:attributes)
         | 
| 190 | 
            +
                end
         | 
| 166 191 | 
             
              end
         | 
| 167 192 |  | 
| 168 193 | 
             
              test "it doesn't cache find queries with options" do
         | 
| 169 | 
            -
                @pies = StandardPie. | 
| 170 | 
            -
                @pie = StandardPie.find(1, : | 
| 171 | 
            -
                assert_queries( | 
| 172 | 
            -
                  assert_equal @pies.collect(&:attributes), ConstantPie. | 
| 173 | 
            -
                  assert_equal @ | 
| 194 | 
            +
                @pies = StandardPie.all(:select => "id").to_a
         | 
| 195 | 
            +
                @pie = StandardPie.find(1, :select => "id")
         | 
| 196 | 
            +
                assert_queries(3) do
         | 
| 197 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.all(:select => "id").collect(&:attributes)
         | 
| 198 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.find(:all, :select => "id").collect(&:attributes)
         | 
| 199 | 
            +
                  assert_equal @pie.attributes, ConstantPie.find(1, :select => "id").attributes
         | 
| 174 200 | 
             
                end
         | 
| 175 | 
            -
                assert_queries( | 
| 176 | 
            -
                  assert_equal @pies.collect(&:attributes), ConstantPie. | 
| 177 | 
            -
                  assert_equal @ | 
| 201 | 
            +
                assert_queries(3) do
         | 
| 202 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.all(:select => "id").collect(&:attributes)
         | 
| 203 | 
            +
                  assert_equal @pies.collect(&:attributes), ConstantPie.find(:all, :select => "id").collect(&:attributes)
         | 
| 204 | 
            +
                  assert_equal @pie.attributes, ConstantPie.find(1, :select => "id").attributes
         | 
| 178 205 | 
             
                end
         | 
| 179 | 
            -
              end
         | 
| 206 | 
            +
              end if DEPRECATED_FINDERS
         | 
| 180 207 |  | 
| 181 208 | 
             
              test "it passes the options preventing caching to the underlying query methods" do
         | 
| 182 | 
            -
                assert_equal nil, ConstantPie. | 
| 183 | 
            -
                assert_equal  | 
| 209 | 
            +
                assert_equal nil, ConstantPie.where(:filling => 'unicorn').first
         | 
| 210 | 
            +
                assert_equal nil, ConstantPie.first(:conditions => {:filling => 'unicorn'}) if DEPRECATED_FINDERS
         | 
| 211 | 
            +
                assert_equal nil, ConstantPie.find(:first, :conditions => {:filling => 'unicorn'}) if DEPRECATED_FINDERS
         | 
| 212 | 
            +
                assert_equal [],  ConstantPie.where(:filling => 'unicorn').all
         | 
| 213 | 
            +
                assert_equal [],  ConstantPie.all(:conditions => {:filling => 'unicorn'}) if DEPRECATED_FINDERS
         | 
| 214 | 
            +
                assert_equal [],  ConstantPie.find(:all,   :conditions => {:filling => 'unicorn'}) if DEPRECATED_FINDERS
         | 
| 184 215 | 
             
              end
         | 
| 185 216 |  | 
| 186 217 | 
             
              test "it creates named class methods if a :name option is given" do
         | 
| @@ -215,14 +246,14 @@ class ConstantTableSaverTest < ActiveRecord::TestCase | |
| 215 246 | 
             
              end
         | 
| 216 247 |  | 
| 217 248 | 
             
              test "it raises the usual exception if asked for a nonexistant records" do
         | 
| 218 | 
            -
                max_id = ConstantPie.all.collect(&:id).max
         | 
| 249 | 
            +
                max_id = ConstantPie.all.to_a.collect(&:id).max
         | 
| 219 250 | 
             
                assert_raises ActiveRecord::RecordNotFound do
         | 
| 220 251 | 
             
                  ConstantPie.find(max_id + 1)
         | 
| 221 252 | 
             
                end
         | 
| 222 253 | 
             
              end
         | 
| 223 254 |  | 
| 224 255 | 
             
              test "it raises the usual exception if asked for a mixture of present records and nonexistant records" do
         | 
| 225 | 
            -
                max_id = ConstantPie.all.collect(&:id).max
         | 
| 256 | 
            +
                max_id = ConstantPie.all.to_a.collect(&:id).max
         | 
| 226 257 | 
             
                assert_raises ActiveRecord::RecordNotFound do
         | 
| 227 258 | 
             
                  ConstantPie.find([max_id, max_id + 1])
         | 
| 228 259 | 
             
                end
         | 
    
        data/test/test_helper.rb
    CHANGED
    
    | @@ -1,24 +1,15 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
              require "../../../config/boot.rb"
         | 
| 3 | 
            -
            else
         | 
| 4 | 
            -
              require 'rubygems'
         | 
| 5 | 
            -
            end
         | 
| 1 | 
            +
            require 'rubygems'
         | 
| 6 2 |  | 
| 3 | 
            +
            gem 'minitest', (ENV['RAILS_VERSION'] =~ /^(3\.|4\.0)/ ? '~> 4.0' : nil)
         | 
| 7 4 | 
             
            gem 'activesupport', ENV['RAILS_VERSION']
         | 
| 8 5 | 
             
            gem 'activerecord',  ENV['RAILS_VERSION']
         | 
| 9 6 |  | 
| 10 | 
            -
            require ' | 
| 7 | 
            +
            require 'minitest/autorun'
         | 
| 11 8 | 
             
            require 'active_support'
         | 
| 12 9 | 
             
            require 'active_support/test_case'
         | 
| 13 10 | 
             
            require 'active_record'
         | 
| 14 11 | 
             
            require 'active_record/fixtures'
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            begin
         | 
| 17 | 
            -
              require 'ruby-debug'
         | 
| 18 | 
            -
              Debugger.start
         | 
| 19 | 
            -
            rescue LoadError
         | 
| 20 | 
            -
              # ruby-debug not installed, no debugging for you
         | 
| 21 | 
            -
            end
         | 
| 12 | 
            +
            require 'byebug' rescue nil
         | 
| 22 13 |  | 
| 23 14 | 
             
            RAILS_ENV = ENV['RAILS_ENV'] ||= 'test'
         | 
| 24 15 |  | 
| @@ -28,4 +19,10 @@ load(File.join(File.dirname(__FILE__), "/schema.rb")) | |
| 28 19 | 
             
            ActiveSupport::TestCase.send(:include, ActiveRecord::TestFixtures) if ActiveRecord.const_defined?('TestFixtures')
         | 
| 29 20 | 
             
            ActiveSupport::TestCase.fixture_path = File.join(File.dirname(__FILE__), "fixtures")
         | 
| 30 21 |  | 
| 22 | 
            +
            ActiveRecord::Base.class_eval do
         | 
| 23 | 
            +
              unless instance_methods.include?(:set_table_name)
         | 
| 24 | 
            +
                eval "class << self; def set_table_name(x); self.table_name = x; end; end"
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             | 
| 31 28 | 
             
            require File.expand_path(File.join(File.dirname(__FILE__), '../init')) # load the plugin
         | 
    
        metadata
    CHANGED
    
    | @@ -1,86 +1,75 @@ | |
| 1 | 
            -
            --- !ruby/object:Gem::Specification | 
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: constant_table_saver
         | 
| 3 | 
            -
            version: !ruby/object:Gem::Version | 
| 4 | 
            -
               | 
| 5 | 
            -
              prerelease: 
         | 
| 6 | 
            -
              segments: 
         | 
| 7 | 
            -
              - 3
         | 
| 8 | 
            -
              - 0
         | 
| 9 | 
            -
              - 1
         | 
| 10 | 
            -
              version: 3.0.1
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 4.0.0
         | 
| 11 5 | 
             
            platform: ruby
         | 
| 12 | 
            -
            authors: | 
| 6 | 
            +
            authors:
         | 
| 13 7 | 
             
            - Will Bryant
         | 
| 14 8 | 
             
            autorequire: 
         | 
| 15 9 | 
             
            bindir: bin
         | 
| 16 10 | 
             
            cert_chain: []
         | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
            - !ruby/object:Gem::Dependency 
         | 
| 11 | 
            +
            date: 2014-05-18 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 21 14 | 
             
              name: activerecord
         | 
| 22 | 
            -
               | 
| 23 | 
            -
             | 
| 24 | 
            -
                 | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
                  - !ruby/object:Gem::Version 
         | 
| 28 | 
            -
                    hash: 3
         | 
| 29 | 
            -
                    segments: 
         | 
| 30 | 
            -
                    - 0
         | 
| 31 | 
            -
                    version: "0"
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - '>='
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '0'
         | 
| 32 20 | 
             
              type: :runtime
         | 
| 33 | 
            -
              version_requirements: *id001
         | 
| 34 | 
            -
            - !ruby/object:Gem::Dependency 
         | 
| 35 | 
            -
              name: rake
         | 
| 36 21 | 
             
              prerelease: false
         | 
| 37 | 
            -
               | 
| 38 | 
            -
                 | 
| 39 | 
            -
                 | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - '>='
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: rake
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - '>='
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0'
         | 
| 46 34 | 
             
              type: :development
         | 
| 47 | 
            -
              version_requirements: *id002
         | 
| 48 | 
            -
            - !ruby/object:Gem::Dependency 
         | 
| 49 | 
            -
              name: sqlite3
         | 
| 50 35 | 
             
              prerelease: false
         | 
| 51 | 
            -
               | 
| 52 | 
            -
                 | 
| 53 | 
            -
                 | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - '>='
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: sqlite3
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - '>='
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '0'
         | 
| 60 48 | 
             
              type: :development
         | 
| 61 | 
            -
               | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - '>='
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0'
         | 
| 62 55 | 
             
            description: |
         | 
| 63 56 | 
             
              Loads all records from the table on first use, and thereafter returns the
         | 
| 64 57 | 
             
              cached (and frozen) records for all find calls.
         | 
| 65 | 
            -
             | 
| 58 | 
            +
             | 
| 66 59 | 
             
              Optionally, creates class-level methods you can use to grab the records,
         | 
| 67 60 | 
             
              named after the name field you specify.
         | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 61 | 
            +
             | 
| 62 | 
            +
             | 
| 70 63 | 
             
              Compatibility
         | 
| 71 64 | 
             
              =============
         | 
| 72 | 
            -
             | 
| 65 | 
            +
             | 
| 73 66 | 
             
              Currently tested against Rails 3.2.13, on Ruby 1.8.7 and 2.0.0p0.
         | 
| 74 67 | 
             
              Was also tested compatible with 2.3.14, 3.0.17, and 3.1.8.
         | 
| 75 | 
            -
             | 
| 76 68 | 
             
            email: will.bryant@gmail.com
         | 
| 77 69 | 
             
            executables: []
         | 
| 78 | 
            -
             | 
| 79 70 | 
             
            extensions: []
         | 
| 80 | 
            -
             | 
| 81 71 | 
             
            extra_rdoc_files: []
         | 
| 82 | 
            -
             | 
| 83 | 
            -
            files: 
         | 
| 72 | 
            +
            files:
         | 
| 84 73 | 
             
            - .gitignore
         | 
| 85 74 | 
             
            - Gemfile
         | 
| 86 75 | 
             
            - MIT-LICENSE
         | 
| @@ -99,38 +88,29 @@ files: | |
| 99 88 | 
             
            - test/test_helper.rb
         | 
| 100 89 | 
             
            homepage: http://github.com/willbryant/constant_table_saver
         | 
| 101 90 | 
             
            licenses: []
         | 
| 102 | 
            -
             | 
| 91 | 
            +
            metadata: {}
         | 
| 103 92 | 
             
            post_install_message: 
         | 
| 104 93 | 
             
            rdoc_options: []
         | 
| 105 | 
            -
             | 
| 106 | 
            -
            require_paths: 
         | 
| 94 | 
            +
            require_paths:
         | 
| 107 95 | 
             
            - lib
         | 
| 108 | 
            -
            required_ruby_version: !ruby/object:Gem::Requirement | 
| 109 | 
            -
               | 
| 110 | 
            -
               | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
              none: false
         | 
| 119 | 
            -
              requirements: 
         | 
| 120 | 
            -
              - - ">="
         | 
| 121 | 
            -
                - !ruby/object:Gem::Version 
         | 
| 122 | 
            -
                  hash: 3
         | 
| 123 | 
            -
                  segments: 
         | 
| 124 | 
            -
                  - 0
         | 
| 125 | 
            -
                  version: "0"
         | 
| 96 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 97 | 
            +
              requirements:
         | 
| 98 | 
            +
              - - '>='
         | 
| 99 | 
            +
                - !ruby/object:Gem::Version
         | 
| 100 | 
            +
                  version: '0'
         | 
| 101 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 102 | 
            +
              requirements:
         | 
| 103 | 
            +
              - - '>='
         | 
| 104 | 
            +
                - !ruby/object:Gem::Version
         | 
| 105 | 
            +
                  version: '0'
         | 
| 126 106 | 
             
            requirements: []
         | 
| 127 | 
            -
             | 
| 128 107 | 
             
            rubyforge_project: 
         | 
| 129 | 
            -
            rubygems_version:  | 
| 108 | 
            +
            rubygems_version: 2.2.2
         | 
| 130 109 | 
             
            signing_key: 
         | 
| 131 | 
            -
            specification_version:  | 
| 132 | 
            -
            summary: Caches the records from fixed tables, and provides convenience methods to | 
| 133 | 
            -
             | 
| 110 | 
            +
            specification_version: 4
         | 
| 111 | 
            +
            summary: Caches the records from fixed tables, and provides convenience methods to
         | 
| 112 | 
            +
              get them.
         | 
| 113 | 
            +
            test_files:
         | 
| 134 114 | 
             
            - test/activerecord_count_queries.rb
         | 
| 135 115 | 
             
            - test/constant_table_saver_test.rb
         | 
| 136 116 | 
             
            - test/database.yml
         |