has_token_id 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ .DS_Store
4
+ coverage
5
+ Gemfile.lock
6
+ pkg/*
7
+ test/dummy_hooks/after_migrate.rb
8
+ test/dummy
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ before_script: "bundle exec dummier"
2
+
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.2
6
+ - 1.9.3
7
+ - rbx
8
+ - ree
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2011 Spencer Steffen and Citrus Media Group.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of Citrus Media Group nor the names of its
15
+ contributors may be used to endorse or promote products derived from this
16
+ software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # HasTokenId [![Build Status](https://secure.travis-ci.org/citrus/has_token_id.png)](http://travis-ci.org/citrus/has_token_id) [![Dependency Status](https://gemnasium.com/citrus/has_token_id.png)](https://gemnasium.com/citrus/has_token_id)
2
+
3
+ Identify your active records with random tokens when you don't want your users to see a sequential ID.
4
+
5
+
6
+ ------------------------------------------------------------------------------
7
+ Installation
8
+ ------------------------------------------------------------------------------
9
+
10
+ Add has_token_id to your Gemfile like so:
11
+
12
+ ```ruby
13
+ gem 'has_token_id', '~> 0.1.0'
14
+ ```
15
+
16
+ Now run `bundle install` and you're good to go!
17
+
18
+
19
+ ------------------------------------------------------------------------------
20
+ Usage
21
+ ------------------------------------------------------------------------------
22
+
23
+ First, add a token to your model's table with a migration:
24
+
25
+ ```ruby
26
+ # Upgrade and existing table
27
+ class AddTokenToItems < ActiveRecord::Migration
28
+ add_column :items, :token, :string
29
+ end
30
+
31
+ # Add to a new table
32
+ class CreateItems < ActiveRecord::Migration
33
+ def change
34
+ create_table :items do |t|
35
+ t.token
36
+ t.string :name
37
+
38
+ t.timestamps
39
+ end
40
+ end
41
+ end
42
+ ```
43
+
44
+
45
+ Now make sure your model knows to use it's token by calling `has_token_id`
46
+
47
+ ```ruby
48
+ class Item < ActiveRecord::Base
49
+ has_token_id
50
+ end
51
+ ```
52
+
53
+ That's basically it! Your Items will now know to use their token as their identifier.
54
+
55
+ Try it out in your `rails console`
56
+
57
+ ```ruby
58
+ @item = Item.create(:name => "Tokenz!")
59
+ #<Item id: 1, token: "Iccfa4bb1613e80097ba9495", name: "Tokenz!", created_at: "2012-01-26 20:17:13", updated_at: "2012-01-26 20:17:13">
60
+ @item.to_param
61
+ # Iccfa4bb1613e80097ba9495
62
+ @item == Item.find("Iccfa4bb1613e80097ba9495")
63
+ # true
64
+ ```
65
+
66
+
67
+ ------------------------------------------------------------------------------
68
+ Options
69
+ ------------------------------------------------------------------------------
70
+
71
+ You can customize has_token_id by setting a few options. Here's the defaults:
72
+
73
+ ```ruby
74
+ :prefix => nil, # if nil use first letter of class name
75
+ :length => 24,
76
+ :param_name => 'token',
77
+ :case_sensitive => false
78
+ ```
79
+
80
+
81
+ Options can be set globally by overwriting the `HasTokenId.default_token_options`
82
+
83
+ ```ruby
84
+ # config/initializers/has_token_id.rb
85
+
86
+ # for one option
87
+ HasTokenId.default_token_options[:prefix] = "OMG"
88
+
89
+ # for multiple options
90
+ HasTokenId.default_token_options.merge!(
91
+ :case_sensitive => true,
92
+ :length => 8
93
+ )
94
+ ```
95
+
96
+
97
+ Options can also be set on a per-class level:
98
+
99
+ ```ruby
100
+ class List < ActiveRecord::Base
101
+ has_token_id :prefix => "LI", :length => 10
102
+ end
103
+
104
+ class Item < ActiveRecord::Base
105
+ has_token_id :prefix => "ITM"
106
+ end
107
+ ```
108
+
109
+
110
+ ------------------------------------------------------------------------------
111
+ Demo
112
+ ------------------------------------------------------------------------------
113
+
114
+ Try out the demo to get a real clear idea of what has_token_id does.
115
+
116
+ ```bash
117
+ git clone git://github.com/citrus/has_token_id.git
118
+ cd has_token_id
119
+ bundle install
120
+ bundle exec dummier
121
+ cd test/dummy
122
+ rails s
123
+ ```
124
+
125
+ Now open your browser to [http://localhost:3000](http://localhost:3000)
126
+
127
+
128
+ ------------------------------------------------------------------------------
129
+ Testing
130
+ ------------------------------------------------------------------------------
131
+
132
+ Testing is done with [minitest](https://github.com/seattlerb/minitest), [minitest_should](https://github.com/citrus/minitest_should) and [dummier](https://github.com/citrus/dummier).
133
+
134
+ To get setup, run the following commands:
135
+
136
+ ```bash
137
+ git clone git://github.com/citrus/has_token_id.git
138
+ cd has_token_id
139
+ bundle install
140
+ bundle exec dummier
141
+ ```
142
+
143
+ Now run the tests with:
144
+
145
+ ```bash
146
+ bundle exec rake
147
+ ```
148
+
149
+
150
+ ------------------------------------------------------------------------------
151
+ License
152
+ ------------------------------------------------------------------------------
153
+
154
+ Copyright (c) 2011 - 2012 Spencer Steffen and Citrus, released under the New BSD License All rights reserved.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ require 'rake/testtask'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test' << 'lib'
8
+ t.pattern = 'test/**/*_test.rb'
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "has_token_id/version"
4
+
5
+ Gem::Specification.new do |s|
6
+
7
+ s.name = "has_token_id"
8
+ s.version = HasTokenId::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Spencer Steffen"]
11
+ s.email = ["spencer@citrusme.com"]
12
+ s.homepage = "https://github.com/citrus/has_token_id"
13
+ s.summary = %q{Identifies your active records with a random token.}
14
+ s.description = %q{Identifies your active records with a random token. For more information, please see the documentation.}
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features,lib/dummy_hooks}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency('activerecord', '>= 3.0.0')
22
+ s.add_dependency('activesupport', '>= 3.0.0')
23
+
24
+ s.add_development_dependency('rails', '>= 3.0.0')
25
+ s.add_development_dependency('dummier', '>= 0.3.0')
26
+ s.add_development_dependency('minitest', '>= 2.0.0')
27
+ s.add_development_dependency('minitest_should', '>= 0.3.1')
28
+ s.add_development_dependency('sqlite3', '>= 1.3.5')
29
+
30
+ end
@@ -0,0 +1,81 @@
1
+ module HasTokenId
2
+ module Concern
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ validates :token, :presence => true, :uniqueness => true
8
+ before_validation :generate_token, :on => :create, :if => proc{|record| record.token.nil? }
9
+ end
10
+
11
+ module ClassMethods
12
+ attr_accessor :has_token_id_options
13
+
14
+ # Default options as well as an overwrite point so you can assign different defaults to different models
15
+ def default_token_options
16
+ return @default_token_options if @default_token_options
17
+ @default_token_options = HasTokenId.default_token_options
18
+ @default_token_options[:prefix] ||= self.name[0, 1]
19
+ @default_token_options
20
+ end
21
+
22
+ # Generates a unique token based on the options
23
+ def generate_unique_token
24
+ record, options = true, self.has_token_id_options
25
+ conditions = {}
26
+ while record
27
+ token = [ options[:prefix], Digest::SHA1.hexdigest((Time.now.to_i * rand()).to_s)].compact.join[0...options[:length].to_i]
28
+ conditions[options[:param_name].to_sym] = token
29
+ record = self.where(conditions).first
30
+ end
31
+ token
32
+ end
33
+
34
+ # Find by token ensuring case sensitivity
35
+ def find_by_case_sensitive_token(token)
36
+ where("#{token_with_table_name} = ?", token).first
37
+ end
38
+
39
+ # Find by token regardless of case
40
+ def find_by_case_insensitive_token(token)
41
+ where("lower(#{token_with_table_name}) = ?", token.downcase).first
42
+ end
43
+
44
+ # Find by token
45
+ def find_by_token(token)
46
+ send(has_token_id_options[:case_sensitive] ? :find_by_case_sensitive_token : :find_by_case_insensitive_token, token)
47
+ end
48
+
49
+ # Find by token if the first param looks like a token, otherwise use super
50
+ def find(*args)
51
+ if args[0].is_a?(String) && args[0].length == has_token_id_options[:length]
52
+ record = find_by_token(args[0])
53
+ end
54
+ record || super(*args)
55
+ end
56
+
57
+ private
58
+
59
+ def token_with_table_name
60
+ [ table_name, has_token_id_options[:param_name] ].join(".")
61
+ end
62
+
63
+ end # ClassMethods
64
+
65
+ module InstanceMethods
66
+
67
+ def to_param
68
+ self.send(self.class.has_token_id_options[:param_name])
69
+ end
70
+
71
+ private
72
+
73
+ def generate_token
74
+ self.token = self.class.generate_unique_token
75
+ end
76
+
77
+ end # InstanceMethods
78
+
79
+ end # Concern
80
+
81
+ end # HasTokenId
@@ -0,0 +1,14 @@
1
+ require 'active_record/connection_adapters/abstract/schema_definitions'
2
+
3
+ module HasTokenId
4
+ module TableDefinition
5
+
6
+ def token(*args)
7
+ options = { :length => HasTokenId.default_token_options[:length] }.merge(args.extract_options!)
8
+ column(:token, :string, options.merge(:nil => false))
9
+ end
10
+
11
+ end
12
+ end
13
+
14
+ ActiveRecord::ConnectionAdapters::TableDefinition.send(:include, HasTokenId::TableDefinition)
@@ -0,0 +1,3 @@
1
+ module HasTokenId
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,31 @@
1
+ require 'digest/sha1'
2
+ require 'has_token_id/concern'
3
+ require 'has_token_id/table_definition'
4
+
5
+ module HasTokenId
6
+
7
+ def self.included(base)
8
+
9
+ base.instance_eval do
10
+
11
+ def has_token_id(options={})
12
+ self.send(:include, HasTokenId::Concern)
13
+ self.has_token_id_options = self.default_token_options.merge(options)
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+
20
+ def self.default_token_options
21
+ @default_token_options ||= {
22
+ :prefix => nil, # if nil use first letter of class name
23
+ :length => 24,
24
+ :param_name => 'token',
25
+ :case_sensitive => false
26
+ }
27
+ end
28
+
29
+ end # Has Token
30
+
31
+ ActiveRecord::Base.send(:include, HasTokenId)
@@ -0,0 +1 @@
1
+ rake "db:migrate", :env => "development"
@@ -0,0 +1,20 @@
1
+ # Generate an Item model
2
+ run "rails g scaffold item name:string"
3
+
4
+ # Add has_token_id to our Item model
5
+ gsub_file "app/models/item.rb", "end", %(
6
+ has_token_id
7
+
8
+ end)
9
+
10
+ # Replace the delete link with a button since we won't have js in the demo
11
+ gsub_file "app/views/items/index.html.erb", %(link_to 'Destroy'), %(button_to 'Destroy')
12
+
13
+ # Ensure our migration is using our `token` TableDefinition
14
+ @migration = File.basename(Dir[File.expand_path("db/migrate/*.rb", destination_path)].last)
15
+ gsub_file File.join("db/migrate/", @migration), "t.string :name", "t.token\n t.string :name"
16
+
17
+ # Route items#index as the root path
18
+ gsub_file "config/routes.rb", "resources :items", %(
19
+ resources :items
20
+ root :to => "items#index")
@@ -0,0 +1,17 @@
1
+ class MiniTest::Should::TestCase
2
+
3
+ # Borrowed from thor .. thanks wycats! :)
4
+ def capture(stream)
5
+ begin
6
+ stream = stream.to_s
7
+ eval "$#{stream} = StringIO.new"
8
+ yield
9
+ result = eval("$#{stream}").string
10
+ ensure
11
+ eval("$#{stream} = #{stream.upcase}")
12
+ end
13
+
14
+ result
15
+ end
16
+
17
+ end
@@ -0,0 +1,27 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ gem "minitest"
4
+
5
+ begin
6
+ require "simplecov"
7
+ SimpleCov.start do
8
+ add_filter do |source_file|
9
+ source_file.filename =~ /dummy/
10
+ end
11
+ end
12
+ rescue LoadError
13
+ end
14
+
15
+ env = File.expand_path("../dummy/config/environment.rb", __FILE__)
16
+ if File.exists?(env)
17
+ require env
18
+ else
19
+ raise LoadError, "Please create the dummy app before running tests. Try running `bundle exec dummier`"
20
+ end
21
+
22
+ require "rails/test_help"
23
+ require "minitest/autorun"
24
+ require "minitest/should"
25
+ require "support/test_case"
26
+
27
+ Rails.backtrace_cleaner.remove_silencers!
@@ -0,0 +1,157 @@
1
+ require "test_helper"
2
+
3
+ # We'll test the test/dummy/app/item.rb model
4
+
5
+ class ConcernTest < MiniTest::Should::TestCase
6
+
7
+ setup do
8
+ # remove all items
9
+ Item.destroy_all
10
+ # reset to defaults
11
+ Item.has_token_id_options.merge!(Item.default_token_options)
12
+ end
13
+
14
+ should "respond to has_token_id" do
15
+ assert Item.respond_to?(:has_token_id)
16
+ end
17
+
18
+ should "set it's token" do
19
+ @item = Item.new(:name => "Something")
20
+ assert @item.valid?
21
+ assert !@item.token.nil?
22
+ assert @item.save
23
+ end
24
+
25
+ should "only set it's token once" do
26
+ @item = Item.new(:name => "Something")
27
+ assert @item.valid?
28
+ token = @item.token
29
+ assert !token.nil?
30
+ @item.name = "Something else"
31
+ assert @item.valid?
32
+ assert_equal token, @item.token
33
+ end
34
+
35
+ should "join token with table name when searching for record" do
36
+ assert_equal "items.token", Item.send(:token_with_table_name)
37
+ end
38
+
39
+ context "with an existing item" do
40
+
41
+ setup do
42
+ @item = Item.create(:name => "Blue Cheese Burger")
43
+ end
44
+
45
+ should "assume token prefix" do
46
+ assert_equal "I", @item.token[0, 1]
47
+ end
48
+
49
+ should "have default options" do
50
+ opts = { :prefix => "I", :length => 24, :param_name => "token", :case_sensitive => false }
51
+ assert_equal opts, Item.has_token_id_options
52
+ end
53
+
54
+ should "have proper token length" do
55
+ assert_equal Item.has_token_id_options[:length], @item.token.length
56
+ end
57
+
58
+ should "have token as to_param" do
59
+ assert_equal @item.to_param, @item.token
60
+ end
61
+
62
+ should "find by token" do
63
+ assert_equal @item, Item.find(@item.token)
64
+ end
65
+
66
+ should "work with token finder method" do
67
+ assert Item.find_by_token(@item.token)
68
+ end
69
+
70
+ should "work with !bang token finder method" do
71
+ assert Item.find_by_token!(@item.token)
72
+ end
73
+
74
+ should "return nil from token finder method when record is not found" do
75
+ assert_equal nil, Item.find_by_token("invalid")
76
+ end
77
+
78
+ should "raise activerecord not found from !bang token finder method when record is not found" do
79
+ assert_raises ActiveRecord::RecordNotFound do
80
+ Item.find_by_token!("invalid")
81
+ end
82
+ end
83
+
84
+ context "when case sensitivity is disabled" do
85
+
86
+ setup do
87
+ Item.has_token_id_options[:case_sensitive] = false
88
+ end
89
+
90
+ should "find by token" do
91
+ assert_equal @item, Item.find(@item.token)
92
+ end
93
+
94
+ should "find by token even if it's all uppercase" do
95
+ assert_equal @item, Item.find(@item.token.upcase)
96
+ end
97
+
98
+ should "find by token even if it's all lowercase" do
99
+ assert_equal @item, Item.find(@item.token.downcase)
100
+ end
101
+
102
+ end
103
+
104
+ context "when case sensitivity is enabled" do
105
+
106
+ setup do
107
+ Item.has_token_id_options[:case_sensitive] = true
108
+ end
109
+
110
+ should "find by token" do
111
+ assert_equal @item, Item.find(@item.token)
112
+ end
113
+
114
+ should "not find by token if it's all uppercase" do
115
+ assert_raises ActiveRecord::RecordNotFound do
116
+ Item.find(@item.token.upcase)
117
+ end
118
+ end
119
+
120
+ should "find by token even if it's all lowercase" do
121
+ assert_raises ActiveRecord::RecordNotFound do
122
+ assert Item.find(@item.token.downcase)
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+
130
+ context "with a long token" do
131
+
132
+ setup do
133
+ Item.has_token_id_options[:length] = 40
134
+ @item = Item.create(:name => "Bacon Cheese Burger")
135
+ end
136
+
137
+ should "have long token" do
138
+ assert_equal 40, @item.token.length
139
+ end
140
+
141
+ end
142
+
143
+ context "with long prefix" do
144
+
145
+ setup do
146
+ Item.has_token_id_options.update(:prefix => "item-", :length => 40)
147
+ @item = Item.create(:name => "Bacon Cheese Burger")
148
+ end
149
+
150
+ should "account for longer prefixes" do
151
+ assert_equal 40, @item.token.length
152
+ assert_match /^item-(.*)/, @item.token
153
+ end
154
+
155
+ end
156
+
157
+ end
@@ -0,0 +1,17 @@
1
+ require "test_helper"
2
+
3
+ class HasTokenIdIdTest < MiniTest::Should::TestCase
4
+
5
+ should "have version" do
6
+ assert_equal String, HasTokenId::VERSION.class
7
+ end
8
+
9
+ should "include HasTokenId" do
10
+ assert ActiveRecord::Base.included_modules.include?(HasTokenId)
11
+ end
12
+
13
+ should "have has_token_id method" do
14
+ assert ActiveRecord::Base.respond_to?(:has_token_id)
15
+ end
16
+
17
+ end
@@ -0,0 +1,26 @@
1
+ require "test_helper"
2
+
3
+ class TableDefinitionTest < MiniTest::Should::TestCase
4
+
5
+ setup do
6
+ @migration = ActiveRecord::Migration.new
7
+ @definition = ActiveRecord::ConnectionAdapters::TableDefinition.new(@migration)
8
+ end
9
+
10
+ should "include token as a migration table definition" do
11
+ assert @definition.respond_to?(:token)
12
+ end
13
+
14
+ should "token definition should be the same as a string column named token" do
15
+ capture(:stdout) {
16
+ assert_equal @definition.column(:token, :string), @definition.token
17
+ }
18
+ end
19
+
20
+ should "token definition should include custom options" do
21
+ capture(:stdout) {
22
+ assert_equal @definition.column(:token, :string, :length => 8), @definition.token(:length => 8)
23
+ }
24
+ end
25
+
26
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: has_token_id
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Spencer Steffen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-27 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &70098471332260 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70098471332260
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70098471329600 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70098471329600
36
+ - !ruby/object:Gem::Dependency
37
+ name: rails
38
+ requirement: &70098471329120 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 3.0.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70098471329120
47
+ - !ruby/object:Gem::Dependency
48
+ name: dummier
49
+ requirement: &70098471328580 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70098471328580
58
+ - !ruby/object:Gem::Dependency
59
+ name: minitest
60
+ requirement: &70098471327820 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 2.0.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70098471327820
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest_should
71
+ requirement: &70098471327140 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: 0.3.1
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70098471327140
80
+ - !ruby/object:Gem::Dependency
81
+ name: sqlite3
82
+ requirement: &70098471326400 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: 1.3.5
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70098471326400
91
+ description: Identifies your active records with a random token. For more information,
92
+ please see the documentation.
93
+ email:
94
+ - spencer@citrusme.com
95
+ executables: []
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - .gitignore
100
+ - .travis.yml
101
+ - Gemfile
102
+ - LICENSE
103
+ - README.md
104
+ - Rakefile
105
+ - has_token_id.gemspec
106
+ - lib/has_token_id.rb
107
+ - lib/has_token_id/concern.rb
108
+ - lib/has_token_id/table_definition.rb
109
+ - lib/has_token_id/version.rb
110
+ - test/dummy_hooks/after_migrate.sample
111
+ - test/dummy_hooks/before_migrate.rb
112
+ - test/support/test_case.rb
113
+ - test/test_helper.rb
114
+ - test/unit/concern_test.rb
115
+ - test/unit/has_token_id_test.rb
116
+ - test/unit/table_definition_test.rb
117
+ homepage: https://github.com/citrus/has_token_id
118
+ licenses: []
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ segments:
130
+ - 0
131
+ hash: -556802150054861821
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ! '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ segments:
139
+ - 0
140
+ hash: -556802150054861821
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 1.8.10
144
+ signing_key:
145
+ specification_version: 3
146
+ summary: Identifies your active records with a random token.
147
+ test_files:
148
+ - test/dummy_hooks/after_migrate.sample
149
+ - test/dummy_hooks/before_migrate.rb
150
+ - test/support/test_case.rb
151
+ - test/test_helper.rb
152
+ - test/unit/concern_test.rb
153
+ - test/unit/has_token_id_test.rb
154
+ - test/unit/table_definition_test.rb