active_record_tweaks 0.1
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/.gitignore +2 -0
- data/.rspec +1 -0
- data/.travis.yml +13 -0
- data/Appraisals +12 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -0
- data/README.md +71 -0
- data/Rakefile +11 -0
- data/active_record_tweaks.gemspec +36 -0
- data/gemfiles/rails3_2.gemfile +8 -0
- data/gemfiles/rails4_0.gemfile +8 -0
- data/lib/active_record_tweaks.rb +12 -0
- data/lib/active_record_tweaks/integration.rb +53 -0
- data/lib/active_record_tweaks/version.rb +3 -0
- data/spec/active_record_tweaks_spec.rb +179 -0
- data/spec/spec_helper.rb +95 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Appraisals
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
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.
|
data/README.md
ADDED
@@ -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
|
+
[](https://travis-ci.org/PikachuEXE/active_record_tweaks)
|
13
|
+
[](http://badge.fury.io/rb/active_record_tweaks)
|
14
|
+
[](https://gemnasium.com/PikachuEXE/active_record_tweaks)
|
15
|
+
[](https://coveralls.io/r/PikachuEXE/active_record_tweaks)
|
16
|
+
[](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
|
+
```
|
data/Rakefile
ADDED
@@ -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,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,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
|
data/spec/spec_helper.rb
ADDED
@@ -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:
|