Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

License

NotificationsYou must be signed in to change notification settings

agilie/activerecord-delay_touching

 
 

Repository files navigation

Note: this version requires ActiveRecord 4.2 or higher. To use ActiveRecord 3.2 through 4.1, use the branchhttps://github.com/godaddy/activerecord-delay_touching/tree/pre-activerecord-4.2.

Batch up your ActiveRecord "touch" operations for better performance.

When you want to invalidate a cache in Rails, you usetouch: true. But whenyou modify a bunch of records that allbelong_to the same owning record, that recordwill be touched N times. It's incredibly slow.

With this gem, alltouch operations are consolidated into as few databaseround-trips as possible. Instead of N touches you get 1 touch.

Installation

Add this line to your application's Gemfile:

gem 'activerecord-delay_touching'

And then execute:

$ bundle

Or install it yourself:

$ gem install activerecord-delay_touching

Usage

The setup:

class Person < ActiveRecord::Base  has_many :pets  accepts_nested_attributes_for :petsendclass Pet < ActiveRecord::Base  belongs_to :person, touch: trueend

Withoutdelay_touching, this simpleupdate in the controller calls@person.touch N times, where N is the number of pets that were updatedvia nested attributes. That's N-1 unnecessary round-trips to the database:

class PeopleController < ApplicationController  def update    ...    #    @person.update(person_params)    ...  endend# SQL (0.1ms)  UPDATE "people" SET "updated_at" = '2014-07-09 19:48:07.137158' WHERE "people"."id" = 1# SQL (0.1ms)  UPDATE "people" SET "updated_at" = '2014-07-09 19:48:07.138457' WHERE "people"."id" = 1# SQL (0.1ms)  UPDATE "people" SET "updated_at" = '2014-07-09 19:48:07.140088' WHERE "people"."id" = 1

Withdelay_touching, @person is touched only once:

ActiveRecord::Base.delay_touching do  @person.update(person_params)end# SQL (0.1ms)  UPDATE "people" SET "updated_at" = '2014-07-09 19:48:07.140088' WHERE "people"."id" = 1

Consolidates Touches Per Table

In the following example, a person gives his pet to another person. ActiveRecordautomatically touches the old person and the new person. Withdelay_touching,this will only make asingle round-trip to the database, settingupdated_atfor all Person records in a single SQL UPDATE statement. Not a big deal when there areonly two touches, but when you're updating records en masse and have a cascadeof hundreds touches, it really is a big deal.

class Pet < ActiveRecord::Base  belongs_to :person, touch: true  def give(to_person)    ActiveRecord::Base.delay_touching do      self.person = to_person      save! # touches old person and new person in a single SQL UPDATE.    end  endend

Cascading Touches

Whendelay_touch runs through and touches everything, it captures additionaltouch calls that might be called as side-effects. (E.g., inafter_touchhandlers.) Then it makes a second pass, batching up those touches as well.

It keeps doing this until there are no more touches, or until the sun swallowsup the earth. Whichever comes first.

Gotchas

Things to note:

  • after_touch callbacks are still fired for every instance, but not until the block is exited.And they won't happen in the same order as they would if you weren't batching up your touches.
  • If you call person1.touch and then person2.touch, and they are two separate instanceswith the same id, only person1'safter_touch handler will be called.

Contributing

  1. Fork it (https://github.com/godaddy/activerecord-delay_touching/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Ruby100.0%

[8]ページ先頭

©2009-2025 Movatter.jp