1. 15 3月, 2013 1 次提交
  2. 10 3月, 2013 1 次提交
  3. 25 2月, 2013 1 次提交
  4. 20 2月, 2013 1 次提交
  5. 22 1月, 2013 1 次提交
  6. 21 1月, 2013 2 次提交
  7. 22 11月, 2012 1 次提交
    • J
      Don't allocate new strings in compiled attribute methods · ae934aef
      Jon Leighton 提交于
      This improves memory and performance without having to use symbols which
      present DoS problems. Thanks @headius and @tenderlove for the
      suggestion.
      
      This was originally committed in
      f1765019, and then reverted in
      d3494903 due to it causing problems in a
      real application. This second attempt should solve that.
      
      Benchmark
      ---------
      
      require 'active_record'
      require 'benchmark/ips'
      
      ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
      
      class Post < ActiveRecord::Base
        connection.create_table :posts, force: true do |t|
          t.string :name
        end
      end
      
      post = Post.create name: 'omg'
      
      Benchmark.ips do |r|
        r.report('Post.new')          { Post.new name: 'omg' }
        r.report('post.name')         { post.name }
        r.report('post.name=')        { post.name = 'omg' }
        r.report('Post.find(1).name') { Post.find(1).name }
      end
      
      Before
      ------
      
      Calculating -------------------------------------
                  Post.new      1419 i/100ms
                 post.name      7538 i/100ms
                post.name=      3024 i/100ms
         Post.find(1).name       243 i/100ms
      -------------------------------------------------
                  Post.new    20637.6 (±12.7%) i/s -     102168 in   5.039578s
                 post.name  1167897.7 (±18.2%) i/s -    5186144 in   4.983077s
                post.name=    64305.6 (±9.6%) i/s -     317520 in   4.998720s
         Post.find(1).name     2678.8 (±10.8%) i/s -      13365 in   5.051265s
      
      After
      -----
      
      Calculating -------------------------------------
                  Post.new      1431 i/100ms
                 post.name      7790 i/100ms
                post.name=      3181 i/100ms
         Post.find(1).name       245 i/100ms
      -------------------------------------------------
                  Post.new    21308.8 (±12.2%) i/s -     105894 in   5.053879s
                 post.name  1534103.8 (±2.1%) i/s -    7634200 in   4.979405s
                post.name=    67441.0 (±7.5%) i/s -     337186 in   5.037871s
         Post.find(1).name     2681.9 (±10.6%) i/s -      13475 in   5.084511s
      ae934aef
  8. 09 11月, 2012 2 次提交
  9. 26 10月, 2012 2 次提交
    • J
      remove unused config option · 6ac33f9e
      Jon Leighton 提交于
      6ac33f9e
    • J
      Remove ActiveRecord::Model · 9e4c41c9
      Jon Leighton 提交于
      In the end I think the pain of implementing this seamlessly was not
      worth the gain provided.
      
      The intention was that it would allow plain ruby objects that might not
      live in your main application to be subclassed and have persistence
      mixed in. But I've decided that the benefit of doing that is not worth
      the amount of complexity that the implementation introduced.
      9e4c41c9
  10. 21 10月, 2012 1 次提交
  11. 20 10月, 2012 1 次提交
    • J
      Get rid of the ActiveRecord::Model::DeprecationProxy thing. · 83846838
      Jon Leighton 提交于
      I think it's going to be too much pain to try to transition the
      :active_record load hook from executing against Base to executing
      against Model.
      
      For example, after Model is included in Base, and modules included in
      Model will no longer get added to the ancestors of Base.
      
      So plugins which wish to be compatible with both Model and Base should
      use the :active_record_model load hook which executes *before* Base gets
      loaded.
      
      In general, ActiveRecord::Model is an advanced feature at the moment and
      probably most people will continue to inherit from ActiveRecord::Base
      for the time being.
      83846838
  12. 23 9月, 2012 2 次提交
  13. 19 9月, 2012 1 次提交
  14. 17 9月, 2012 1 次提交
  15. 15 9月, 2012 1 次提交
    • J
      Revert "create a transaction object and point AR objects at that object during a" · b89ffe7f
      Jon Leighton 提交于
      This reverts commit c24c8852.
      
      Here's the explanation I just sent to @tenderlove:
      
      Hey,
      
      I've been thinking about about the transaction memory leak thing that we
      were discussing.
      
      Example code:
      
      post = nil
      Post.transaction do
        N.times { post = Post.create }
      end
      
      Post.transaction is going to create a real transaction and there will
      also be a (savepoint) transaction inside each Post.create.
      
      In an idea world, we'd like all but the last Post instance to be GC'd,
      and for the last Post instance to receive its after_commit callback when
      Post.transaction returns.
      
      I can't see how this can work using your solution where the Post itself
      holds a reference to the transaction it is in; when Post.transaction
      returns, control does not switch to any of Post's instance methods, so
      it can't trigger the callbacks itself.
      
      What we really want is for the transaction itself to hold weak
      references to the objects within the transaction. So those objects can
      be GC'd, but if they are not GC'd then the transaction can iterate them
      and execute their callbacks.
      
      I've looked into WeakRef implementations that are available. On 1.9.3,
      the stdlib weakref library is broken and we shouldn't use it.
      
      There is a better implementation here:
      
      https://github.com/bdurand/ref/blob/master/lib/ref/weak_reference/pure_ruby.rb
      
      We could use that, either by pulling in the gem or just copying the code
      in, but it still suffers from the limitation that it uses ObjectSpace
      finalizers.
      
      In my testing, this finalizers make GC quite expensive:
      https://gist.github.com/3722432
      
      Ruby 2.0 will have a native WeakRef implementation (via
      ObjectSpace::WeakMap), hence won't be reliant on finalizers:
      http://bugs.ruby-lang.org/issues/4168
      
      So the ultimate solution will be for everyone to use Ruby 2.0, and for
      us to just use ObjectSpace::WeakMap.
      
      In the meantime, we have basically 3 options:
      
      The first is to leave it as it is.
      
      The second is to use a finalizer-based weakref implementation and take
      the GC perf hit.
      
      The final option is to store object ids rather than the actual objects.
      Then use ObjectSpace._id2ref to deference the objects at the end of the
      transaction, if they exist. This won't stop memory use growing within
      the transaction, but it'll grow more slowly.
      
      I benchmarked the performance of _id2ref this if the object does or does
      not exist: https://gist.github.com/3722550
      
      If it does exist it seems decent, but it's hugely more expensive if it
      doesn't, probably because we have to do the rescue nil.
      
      Probably most of the time the objects will exist. However the point of
      doing this optimisation is to allow people to create a large number of
      objects inside a transaction and have them be GC'd. So for that use
      case, we'd be replacing one problem with another. I'm not sure which of
      the two problems is worse.
      
      My feeling is that we should just leave this for now and come back to it
      when Ruby 2.0 is out.
      
      I'm going to revert your commit because I can't see how it solves this.
      Hope you don't mind... if I've misunderstood then let me know!
      
      Jon
      b89ffe7f
  16. 08 9月, 2012 2 次提交
  17. 21 8月, 2012 1 次提交
  18. 18 8月, 2012 2 次提交
    • J
      Avoid #any? · 2ff47c48
      Jon Leighton 提交于
      any? will check that each item in the array is truthy, as opposed to
      !empty? which will simply check that the array has length. For an empty
      array, !empty? still seems to be faster than any?
      2ff47c48
    • J
      Avoid deep_dup when intantiating. · 1b2c9077
      Jon Leighton 提交于
      deep_dup is slow. we only need to dup the values, so just do that
      directly.
      1b2c9077
  19. 11 8月, 2012 1 次提交
    • J
      Remove the dependent_restrict_raises option. · 5ad79989
      Jon Leighton 提交于
      It's not really a good idea to have this as a global config option. We
      should allow people to specify the behaviour per association.
      
      There will now be two new values:
      
      * :dependent => :restrict_with_exception implements the current
        behaviour of :restrict. :restrict itself is deprecated in favour of
        :restrict_with_exception.
      * :dependent => :restrict_with_error implements the new behaviour - it
        adds an error to the owner if there are dependent records present
      
      See #4727 for the original discussion of this.
      5ad79989
  20. 03 8月, 2012 2 次提交
  21. 28 7月, 2012 1 次提交
  22. 16 7月, 2012 1 次提交
  23. 19 6月, 2012 1 次提交
    • S
      Removing composed_of from ActiveRecord. · 14fc8b34
      Steve Klabnik 提交于
      This feature adds a lot of complication to ActiveRecord for dubious
      value. Let's talk about what it does currently:
      
      class Customer < ActiveRecord::Base
        composed_of :balance, :class_name => "Money", :mapping => %w(balance amount)
      end
      
      Instead, you can do something like this:
      
          def balance
            @balance ||= Money.new(value, currency)
          end
      
          def balance=(balance)
            self[:value] = balance.value
            self[:currency] = balance.currency
            @balance = balance
          end
      
      Since that's fairly easy code to write, and doesn't need anything
      extra from the framework, if you use composed_of today, you'll
      have to add accessors/mutators like that.
      
      Closes #1436
      Closes #2084
      Closes #3807
      14fc8b34
  24. 16 6月, 2012 1 次提交
  25. 10 6月, 2012 1 次提交
    • A
      Ensure that mass assignment options are preserved · c2e61aa6
      Andrew White 提交于
      There are two possible scenarios where the @mass_assignment_options
      instance variable can become corrupted:
      
      1. If the assign_attributes doesn't complete correctly, then
         subsequent calls to a nested attribute assignment method will use
         whatever options were passed to the previous assign_attributes call.
      
      2. With nested assign_attributes calls, the inner call will overwrite
         the current options. This will only affect nested attributes as the
         attribute hash is sanitized before any methods are called.
      
      To fix this we save the current options in a local variable and then
      restore these options in an ensure block.
      c2e61aa6
  26. 30 5月, 2012 1 次提交
  27. 27 5月, 2012 1 次提交
  28. 18 5月, 2012 1 次提交
  29. 17 5月, 2012 1 次提交
  30. 15 5月, 2012 3 次提交
  31. 12 5月, 2012 1 次提交