rein 0.3.0 → 0.4.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/README.md +51 -5
- data/lib/rein/constraint/inclusion.rb +5 -2
- data/lib/rein/constraint/numericality.rb +1 -1
- data/lib/rein/version.rb +1 -1
- data/lib/rein.rb +12 -9
- metadata +7 -10
data/README.md
CHANGED
@@ -1,21 +1,67 @@
|
|
1
1
|
# Rein
|
2
2
|
|
3
|
-
Database constraints made easy for ActiveRecord.
|
3
|
+
Database constraints made easy for ActiveRecord. Rein currently supports PostgreSQL and MySQL (foreign keys only).
|
4
4
|
|
5
5
|
|
6
6
|
## Introduction
|
7
7
|
|
8
|
-
|
8
|
+
[Database integrity](http://en.wikipedia.org/wiki/Database_integrity) is a "good thing". Constraining the allowed values in your database at the database-level (rather than solely at the application-level) is a much more robust way of ensuring your data stays sane.
|
9
9
|
|
10
|
-
ActiveRecord doesn't
|
10
|
+
Unfortunately, ActiveRecord doesn't encourage (or even allow) you to use database integrity without resorting to hand-crafted SQL. Rein adds a handful of methods to your ActiveRecord migrations so that you can easily tame your database.
|
11
11
|
|
12
12
|
|
13
13
|
## Quick Start
|
14
14
|
|
15
|
-
|
15
|
+
Install the gem:
|
16
16
|
|
17
17
|
gem install rein
|
18
18
|
|
19
|
-
|
19
|
+
Add a foreign key constraint:
|
20
|
+
|
21
|
+
add_foreign_key_constraint :books, :authors
|
22
|
+
|
23
|
+
Add a numericality constraint (PostgreSQL only):
|
20
24
|
|
21
25
|
add_numericality_constraint :books, :publication_month, :greater_than_or_equal_to => 1, :less_than_or_equal_to => 12
|
26
|
+
|
27
|
+
Add an inclusion constraint (PostgreSQL only):
|
28
|
+
|
29
|
+
add_inclusion_constraint :books, :state, :in => %w(available on_loan)
|
30
|
+
|
31
|
+
|
32
|
+
## Example
|
33
|
+
|
34
|
+
Let's look at constraining values for this simple library application.
|
35
|
+
|
36
|
+
Here we have a table of authors:
|
37
|
+
|
38
|
+
create_table :authors do |t|
|
39
|
+
t.string :name, :null => false
|
40
|
+
|
41
|
+
t.timestamps
|
42
|
+
end
|
43
|
+
|
44
|
+
And here we have a table of books:
|
45
|
+
|
46
|
+
create_table :books do |t|
|
47
|
+
t.belongs_to :author, :null => false
|
48
|
+
t.string :name, :null => false
|
49
|
+
t.string :state, :null => false
|
50
|
+
t.integer :published_year, :null => false
|
51
|
+
t.integer :published_month, :null => false
|
52
|
+
|
53
|
+
t.timestamps
|
54
|
+
end
|
55
|
+
|
56
|
+
# A book should always belong to an author.
|
57
|
+
# The database should prevent us from deleteing an author who has books.
|
58
|
+
add_foreign_key_constraint :books, :authors, :on_delete => :restrict
|
59
|
+
|
60
|
+
# Our library doesn't deal in classics.
|
61
|
+
add_numericality_constraint :books, :published_year, :greater_than => 1980
|
62
|
+
|
63
|
+
# Month is always between 1 and 12.
|
64
|
+
add_numericality_constraint :books, :published_month, :greater_than_or_equal_to => 1, :less_than_or_equal_to => 12
|
65
|
+
|
66
|
+
# State is always either "available" or "on_loan".
|
67
|
+
add_inclusion_constraint :books, :state, :in => %w(available on_loan)
|
@@ -1,10 +1,13 @@
|
|
1
|
+
require 'active_record/connection_adapters/abstract/quoting'
|
2
|
+
|
1
3
|
module RC
|
2
4
|
module Inclusion
|
5
|
+
include ActiveRecord::ConnectionAdapters::Quoting
|
6
|
+
|
3
7
|
def add_inclusion_constraint(table, attribute, options = {})
|
4
8
|
name = "#{table}_#{attribute}"
|
5
|
-
values = options[:in].map {|
|
9
|
+
values = options[:in].map {|value| quote(value) }.join(", ")
|
6
10
|
conditions = "#{attribute} IN (#{values})"
|
7
|
-
|
8
11
|
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
9
12
|
end
|
10
13
|
end
|
data/lib/rein/version.rb
CHANGED
data/lib/rein.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/hash'
|
2
|
-
|
3
1
|
module Rein
|
4
2
|
module Constraint
|
5
3
|
end
|
@@ -7,16 +5,21 @@ end
|
|
7
5
|
|
8
6
|
RC = Rein::Constraint
|
9
7
|
|
8
|
+
require 'active_record'
|
9
|
+
require 'active_support/core_ext/hash'
|
10
|
+
|
10
11
|
require 'rein/constraint/foreign_key'
|
11
12
|
require 'rein/constraint/inclusion'
|
12
13
|
require 'rein/constraint/numericality'
|
13
|
-
require 'rein/version'
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
module ActiveRecord::ConnectionAdapters
|
16
|
+
class MysqlAdapter < AbstractAdapter
|
17
|
+
include RC::ForeignKey
|
18
|
+
end
|
19
|
+
|
20
|
+
class PostgreSQLAdapter < AbstractAdapter
|
21
|
+
include RC::ForeignKey
|
22
|
+
include RC::Inclusion
|
23
|
+
include RC::Numericality
|
21
24
|
end
|
22
25
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 4
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Josh Bassett
|
@@ -14,22 +14,19 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-08-
|
17
|
+
date: 2010-08-29 00:00:00 +10:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
21
|
+
name: activerecord
|
22
22
|
requirement: &id001 !ruby/object:Gem::Requirement
|
23
23
|
none: false
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
segments:
|
28
|
-
- 3
|
29
|
-
- 0
|
30
28
|
- 0
|
31
|
-
|
32
|
-
version: 3.0.0.rc
|
29
|
+
version: "0"
|
33
30
|
type: :runtime
|
34
31
|
prerelease: false
|
35
32
|
version_requirements: *id001
|
@@ -169,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
169
166
|
requirements:
|
170
167
|
- - ">="
|
171
168
|
- !ruby/object:Gem::Version
|
172
|
-
hash:
|
169
|
+
hash: 1339191596134317982
|
173
170
|
segments:
|
174
171
|
- 0
|
175
172
|
version: "0"
|