active_record_tweaks 0.1

This diff has not been reviewed by any users.
Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e6c504a0ed5232370690f5499f743c5c7581dab0
4
+ data.tar.gz: 0b05eb09c16078bd87853e88f0d5d8a771102212
5
+ SHA512:
6
+ metadata.gz: b65f4621e384155be04e7ea35a644a528ba2d7758625a310f8241fee90dca37c42703592e83d1fa48eefcf9063ae9cc7cbe1cd6da0dcb87b274e5f4f498285f3
7
+ data.tar.gz: 1c70119ae53329e44a4f24a76cbe169db8f9789b9a1423fa32198d95698e7941f704575d4770f12d964925e140a40f5a3d4808d64913f092747f7ba409e169c3
@@ -0,0 +1,2 @@
1
+ gemfiles/*.gemfile.lock
2
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,13 @@
1
+ script: "bundle exec rspec"
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - 2.0.0
6
+ gemfile:
7
+ - gemfiles/rails3_2.gemfile
8
+ - gemfiles/rails4_0.gemfile
9
+ matrix:
10
+ exclude:
11
+ - rvm: 1.9.2
12
+ gemfile: gemfiles/rails4_0.gemfile
13
+
@@ -0,0 +1,12 @@
1
+
2
+ appraise "rails3-2" do
3
+ version = "3.2.15"
4
+ gem 'activesupport', version
5
+ gem 'actionpack', version
6
+ end
7
+
8
+ appraise "rails4-0" do
9
+ version = "4.0.0"
10
+ gem 'activesupport', version
11
+ gem 'actionpack', version
12
+ end
@@ -0,0 +1,5 @@
1
+ ### Changelog
2
+
3
+
4
+ - **0.1**
5
+ - Initial Release
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 PikachuEXE
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,71 @@
1
+ Active Record Tweaks
2
+ ===========
3
+
4
+ Active Record is great, but could be better. Here are some tweaks for it.
5
+
6
+ ### Support
7
+ ===========
8
+ Tested against:
9
+ - Active Record of version `3.2` and `4.0`
10
+ - Ruby `1.9.3`, `2.0.0` (except Rails 4 with `1.9.2`)
11
+
12
+ [![Build Status](https://travis-ci.org/PikachuEXE/active_record_tweaks.png?branch=master)](https://travis-ci.org/PikachuEXE/active_record_tweaks)
13
+ [![Gem Version](https://badge.fury.io/rb/active_record_tweaks.png)](http://badge.fury.io/rb/active_record_tweaks)
14
+ [![Dependency Status](https://gemnasium.com/PikachuEXE/active_record_tweaks.png)](https://gemnasium.com/PikachuEXE/active_record_tweaks)
15
+ [![Coverage Status](https://coveralls.io/repos/PikachuEXE/active_record_tweaks/badge.png)](https://coveralls.io/r/PikachuEXE/active_record_tweaks)
16
+ [![Code Climate](https://codeclimate.com/github/PikachuEXE/active_record_tweaks.png)](https://codeclimate.com/github/PikachuEXE/active_record_tweaks)
17
+
18
+ Install
19
+ =======
20
+
21
+ ```ruby
22
+ gem 'active_record_tweaks'
23
+ ```
24
+
25
+ Usage
26
+ =====
27
+
28
+ Either include it in specific record or just `ActiveRecord::Base`
29
+ ```ruby
30
+ class SomeRecord
31
+ include ActiveRecordTweaks
32
+ end
33
+
34
+ # or
35
+
36
+ # In a initialzer
37
+ ActiveRecord::Base.send(:include, ActiveRecordTweaks)
38
+ ```
39
+
40
+
41
+ ### `#cache_key_without_timestamp`
42
+ Nothing special, just like `record.cache_key`
43
+ But it has no timestamp so you can use it for scoped cache key
44
+ (e.g. When caching with Cookie, which you want to control the expiry time independent of record update time)
45
+ Usage:
46
+ ```ruby
47
+ # Just like using #cache_key
48
+ record.cache_key_without_timestamp
49
+ ```
50
+
51
+
52
+ ### `.cache_key`
53
+ There is no class level cache key for ActiveRecord at the moment (4.0.1)
54
+ Passing an array to `cache_digest` could lead to performance issue and the key can become too long when collection is big
55
+ ([rails#12726](https://github.com/rails/rails/pull/12726))
56
+ This is used for getting a cache key for a ActiveRecord class for all record (I don't know how to write one for `Relation`, could be similar)
57
+ You can use it for class level caching (like displaying all Categories or a random list of 5 users
58
+ And the cache would only expire when there is any record created, updated, or deleted (since `count` and maximum of `updated_at` are used)
59
+ ```ruby
60
+ Person.count # => 1000
61
+ Person.maximum(:updated_at) # => 20131106012125528738000
62
+ Person.cache_key # => "people/all/1000-20131106012125528738000"
63
+ ```
64
+ Usage:
65
+ ```ruby
66
+ RecordClass.cache_key
67
+ ```
68
+ You can also use it with multiple records (Rails 4 Record might have `updated_at` and `updated_on`)
69
+ ```ruby
70
+ RecordClass.cache_key(:updated_at, :updated_on)
71
+ ```
@@ -0,0 +1,11 @@
1
+ require 'appraisal'
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ require 'bundler/gem_tasks'
5
+ require 'rspec/core/rake_task'
6
+
7
+ task :default do
8
+ sh "rake appraisal:install && rake appraisal spec"
9
+ end
10
+
11
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ author_name = 'PikachuEXE'
5
+ gem_name = 'active_record_tweaks'
6
+
7
+ require "#{gem_name}/version"
8
+
9
+ Gem::Specification.new do |s|
10
+ s.platform = Gem::Platform::RUBY
11
+ s.name = gem_name
12
+ s.version = ActiveRecordTweaks::VERSION
13
+ s.summary = 'Some Tweaks for ActiveRecord'
14
+ s.description = 'ActiveRecord is great, but could be better. Here are some tweaks for it.'
15
+
16
+ s.license = 'MIT'
17
+
18
+ s.authors = [author_name]
19
+ s.email = ['pikachuexe@gmail.com']
20
+ s.homepage = "http://github.com/#{author_name}/#{gem_name}"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ['lib']
26
+
27
+ s.add_dependency 'activerecord', '>= 3.2.0', '< 5.0.0'
28
+ s.add_dependency 'activesupport', '>= 3.2.0', '< 5.0.0'
29
+
30
+ s.add_development_dependency 'rake'
31
+ s.add_development_dependency 'appraisal'
32
+ s.add_development_dependency 'rspec'
33
+ s.add_development_dependency 'sqlite3'
34
+ s.add_development_dependency 'database_cleaner'
35
+ s.add_development_dependency 'coveralls'
36
+ end
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "3.2.15"
6
+ gem "actionpack", "3.2.15"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "4.0.0"
6
+ gem "actionpack", "4.0.0"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,12 @@
1
+ require 'active_support/concern'
2
+
3
+ require 'active_record_tweaks/version'
4
+ require 'active_record_tweaks/integration'
5
+
6
+ module ActiveRecordTweaks
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ include Integration
11
+ end
12
+ end
@@ -0,0 +1,53 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActiveRecordTweaks
4
+ module Integration
5
+ extend ActiveSupport::Concern
6
+
7
+ # Returns a cache key that can be used to identify this record.
8
+ # Timestamp is not used to allow custom caching expiration
9
+ # (e.g. Cookie based caching with expiration )
10
+ #
11
+ # Product.new.cache_key # => "products/new"
12
+ # Product.find(5).cache_key # => "products/5" (updated_at not available)
13
+ # Person.find(5).cache_key # => "people/5" (updated_at available)
14
+ def cache_key_without_timestamp
15
+ case
16
+ when new_record?
17
+ "#{self.class.model_name.cache_key}/new"
18
+ else
19
+ "#{self.class.model_name.cache_key}/#{id}"
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ # Returns a cache key for the ActiveRecord class based
25
+ # based on count and maximum value of update timestamp columns
26
+ # (e.g. Cookie based caching with expiration)
27
+ #
28
+ # Product.cache_key # => "products/0" (empty, has updated timestamp columns or not)
29
+ # Product.cache_key # => "products/1" (not empty but has no updated timestamp columns)
30
+ # Person.cache_key # => "people/1-20071224150000" (not empty and has updated timestamp columns)
31
+ #
32
+ # @param [Array<String, Symbol>] args The column name with timestamp to check
33
+ def cache_key(*args)
34
+ timestamp_columns = args.empty? ? [:updated_at] : args
35
+
36
+ if timestamp = max_updated_column_timestamp_for_cache_key(timestamp_columns)
37
+ timestamp = timestamp.utc.to_s(cache_timestamp_format)
38
+ "#{self.model_name.cache_key}/all/#{self.count}-#{timestamp}"
39
+ else
40
+ "#{self.model_name.cache_key}/all/#{self.count}"
41
+ end
42
+ end
43
+
44
+ def max_updated_column_timestamp_for_cache_key(timestamp_columns)
45
+ available_timestamp_columns = timestamp_columns.select { |c| self.column_names.include?(c.to_s) }
46
+
47
+ if (timestamps = available_timestamp_columns.map { |column| self.maximum(column) }.compact).present?
48
+ timestamps.map { |ts| ts.to_time }.max
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveRecordTweaks
2
+ VERSION = '0.1'.freeze
3
+ end
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parent do
4
+ describe 'included modules' do
5
+ it do
6
+ described_class.ancestors.should include(ActiveRecordTweaks)
7
+ end
8
+ end
9
+
10
+ describe '::Integration' do
11
+ describe '#cache_key_without_timestamp' do
12
+ subject { record.cache_key_without_timestamp }
13
+
14
+
15
+ context 'when record is a new record' do
16
+ let(:record) { Parent.new }
17
+
18
+ it 'works like #cache_key' do
19
+ should eq "#{record.class.model_name.cache_key}/new"
20
+ end
21
+ end
22
+
23
+ context 'when record is an existing record' do
24
+ let(:record) { Parent.create! }
25
+
26
+
27
+ context 'and update_at is nil' do
28
+ before { record.update_attributes!(updated_at: nil) }
29
+
30
+ it 'works like #cache_key' do
31
+ should eq "#{record.class.model_name.cache_key}/#{record.id}"
32
+ end
33
+ end
34
+
35
+ context 'and update_at is present' do
36
+ it 'works like #cache_key when updated_at is nil' do
37
+ should eq "#{record.class.model_name.cache_key}/#{record.id}"
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'when record has no update_at column' do
43
+ let!(:record) { Stone.create }
44
+
45
+ it 'works like #cache_key when updated_at is nil' do
46
+ should eq "#{record.class.model_name.cache_key}/#{record.id}"
47
+ end
48
+ end
49
+ end
50
+
51
+ describe '.cache_key' do
52
+ subject { klass.cache_key }
53
+
54
+ context 'when a class has no update_at column' do
55
+ let(:klass) { Stone }
56
+
57
+ context 'and has no record' do
58
+ before { klass.count.should eq 0 }
59
+
60
+ it { should match /\/#{klass.count}$/ }
61
+ end
62
+ context 'and has a record' do
63
+ before { klass.create! }
64
+
65
+ it { should match /\/#{klass.count}$/ }
66
+ end
67
+ end
68
+
69
+ context 'when a class has updated_at column' do
70
+ let(:klass) { Parent }
71
+
72
+ context 'and has no record' do
73
+ before { klass.count.should eq 0 }
74
+
75
+ it { should match /\/#{klass.count}$/ }
76
+ end
77
+
78
+ context 'and has a record' do
79
+ let!(:parent) { klass.create! }
80
+
81
+ it { should eq "parents/all/#{klass.count}-#{klass.maximum(:updated_at).utc.to_s(:nsec)}" }
82
+
83
+ context 'when record all has nil updated timestamps' do
84
+ before { klass.update_all(updated_at: nil) }
85
+
86
+ it { should match /\/#{klass.count}$/ }
87
+ end
88
+
89
+ describe 'precision' do
90
+ let!(:child) { Child.create!(parent: parent) }
91
+ let!(:old_cache_key) { klass.cache_key }
92
+ let(:new_cache_key) { klass.cache_key }
93
+
94
+ subject { new_cache_key }
95
+
96
+ context 'when self touched' do
97
+ before { parent.touch }
98
+
99
+ it { should_not eq old_cache_key }
100
+ end
101
+
102
+ context 'when child touched' do
103
+ before { child.touch }
104
+
105
+ it { should_not eq old_cache_key }
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ context 'when a class has updated_at AND updated_on column' do
112
+ let(:klass) { Person }
113
+
114
+ context 'when getting cache_key using update_on column' do
115
+ subject { klass.cache_key(:updated_on) }
116
+
117
+ context 'and has no record' do
118
+ before { klass.count.should eq 0 }
119
+
120
+ it { should match /\/#{klass.count}$/ }
121
+ end
122
+ context 'and has a record' do
123
+ let!(:person) { klass.create! }
124
+
125
+ context 'and it has updated_at value only' do
126
+ before { person.update_attributes!(updated_at: Time.now, updated_on: nil) }
127
+
128
+ it { should eq "people/all/#{klass.count}" }
129
+ end
130
+
131
+ context 'and it has updated_on value only' do
132
+ before { person.update_attributes!(updated_at: nil, updated_on: Time.now) }
133
+
134
+ it { should eq "people/all/#{klass.count}-#{klass.maximum(:updated_on).utc.to_s(:nsec)}" }
135
+ end
136
+ end
137
+ end
138
+
139
+ context 'when getting cache_key using both columns' do
140
+ subject { klass.cache_key(:updated_at, :updated_on) }
141
+
142
+ context 'and has no record' do
143
+ before { klass.count.should eq 0 }
144
+
145
+ it { should match /\/#{klass.count}$/ }
146
+ end
147
+ context 'and has a record' do
148
+ let!(:person) { klass.create! }
149
+
150
+ context 'and it has updated_on value only' do
151
+ before { person.update_attributes!(updated_at: nil, updated_on: Time.now) }
152
+
153
+ it { should eq "people/all/#{klass.count}-#{klass.maximum(:updated_on).utc.to_s(:nsec)}" }
154
+ end
155
+
156
+ context 'and it has newer updated_at' do
157
+ before { person.update_attributes!(updated_at: Time.now + 3600, updated_on: Time.now) }
158
+
159
+ it { should eq "people/all/#{klass.count}-#{klass.maximum(:updated_at).utc.to_s(:nsec)}" }
160
+ end
161
+
162
+ context 'and it has newer updated_on' do
163
+ before { person.update_attributes!(updated_at: Time.now , updated_on: Time.now+ 3600) }
164
+
165
+ it { should eq "people/all/#{klass.count}-#{klass.maximum(:updated_on).utc.to_s(:nsec)}" }
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ context 'when a class has custom timestamp format' do
172
+ let(:klass) { Animal }
173
+ let!(:record) { klass.create! }
174
+
175
+ it { should eq "animals/all/#{klass.count}-#{klass.maximum(:updated_at).utc.to_s(:number)}" }
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,95 @@
1
+ if ENV["TRAVIS"]
2
+ require 'coveralls'
3
+ Coveralls.wear!('rails')
4
+ end
5
+
6
+ require 'active_record'
7
+ require 'active_record_tweaks'
8
+
9
+ require 'database_cleaner'
10
+ require 'logger'
11
+
12
+ # ActiveRecord::Base.logger = Logger.new(STDOUT) # for easier debugging
13
+
14
+ RSpec.configure do |config|
15
+ config.before(:suite) do
16
+ DatabaseCleaner.strategy = :transaction
17
+ end
18
+
19
+ config.before do
20
+ DatabaseCleaner.start
21
+ end
22
+
23
+ config.after do
24
+ DatabaseCleaner.clean
25
+ end
26
+ end
27
+
28
+ ActiveRecord::Base.send(:include, ActiveRecordTweaks)
29
+
30
+ # connect
31
+ ActiveRecord::Base.establish_connection(
32
+ :adapter => "sqlite3",
33
+ :database => ":memory:"
34
+ )
35
+
36
+ # create tables
37
+ ActiveRecord::Schema.define(:version => 1) do
38
+ create_table :stones do |t|
39
+ end
40
+
41
+ create_table :animals do |t|
42
+ t.datetime :created_at
43
+ t.datetime :updated_at
44
+ end
45
+
46
+ create_table :parents do |t|
47
+ t.datetime :created_at
48
+ t.datetime :updated_at
49
+ end
50
+
51
+ create_table :children do |t|
52
+ t.integer :parent_id
53
+
54
+ t.datetime :created_at
55
+ t.datetime :updated_at
56
+ end
57
+
58
+ create_table :people do |t|
59
+ t.datetime :created_at
60
+ t.datetime :updated_at
61
+ t.datetime :created_on
62
+ t.datetime :updated_on
63
+ end
64
+ end
65
+
66
+ # Setup models
67
+
68
+ # Default cache timestamp format are different for Rails 3 and 4 are different,
69
+ # So set it explictly here
70
+ class Stone < ActiveRecord::Base
71
+ end
72
+
73
+ class Animal < ActiveRecord::Base
74
+ self.cache_timestamp_format = :number
75
+ end
76
+
77
+ class Parent < ActiveRecord::Base
78
+ self.cache_timestamp_format = :nsec
79
+
80
+ has_many :children, inverse_of: :parent
81
+ end
82
+
83
+ class Child < ActiveRecord::Base
84
+ self.cache_timestamp_format = :nsec
85
+
86
+ belongs_to :parent, inverse_of: :children, touch: true
87
+ end
88
+
89
+ class Person < ActiveRecord::Base
90
+ self.cache_timestamp_format = :nsec
91
+ end
92
+
93
+
94
+ RSpec.configure do |config|
95
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_record_tweaks
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - PikachuEXE
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.2.0
20
+ - - <
21
+ - !ruby/object:Gem::Version
22
+ version: 5.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.0
30
+ - - <
31
+ - !ruby/object:Gem::Version
32
+ version: 5.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: activesupport
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: 3.2.0
40
+ - - <
41
+ - !ruby/object:Gem::Version
42
+ version: 5.0.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: 3.2.0
50
+ - - <
51
+ - !ruby/object:Gem::Version
52
+ version: 5.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: appraisal
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: sqlite3
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: database_cleaner
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ - !ruby/object:Gem::Dependency
124
+ name: coveralls
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ description: ActiveRecord is great, but could be better. Here are some tweaks for
138
+ it.
139
+ email:
140
+ - pikachuexe@gmail.com
141
+ executables: []
142
+ extensions: []
143
+ extra_rdoc_files: []
144
+ files:
145
+ - .gitignore
146
+ - .rspec
147
+ - .travis.yml
148
+ - Appraisals
149
+ - CHANGELOG.md
150
+ - Gemfile
151
+ - LICENSE
152
+ - README.md
153
+ - Rakefile
154
+ - active_record_tweaks.gemspec
155
+ - gemfiles/rails3_2.gemfile
156
+ - gemfiles/rails4_0.gemfile
157
+ - lib/active_record_tweaks.rb
158
+ - lib/active_record_tweaks/integration.rb
159
+ - lib/active_record_tweaks/version.rb
160
+ - spec/active_record_tweaks_spec.rb
161
+ - spec/spec_helper.rb
162
+ homepage: http://github.com/PikachuEXE/active_record_tweaks
163
+ licenses:
164
+ - MIT
165
+ metadata: {}
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - '>='
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubyforge_project:
182
+ rubygems_version: 2.1.9
183
+ signing_key:
184
+ specification_version: 4
185
+ summary: Some Tweaks for ActiveRecord
186
+ test_files:
187
+ - spec/active_record_tweaks_spec.rb
188
+ - spec/spec_helper.rb
189
+ has_rdoc: