rails 4.2.6.rc1 → 5.2.8.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rails might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/README.md +24 -12
- metadata +54 -248
- data/guides/CHANGELOG.md +0 -73
- data/guides/Rakefile +0 -79
- data/guides/assets/images/akshaysurve.jpg +0 -0
- data/guides/assets/images/belongs_to.png +0 -0
- data/guides/assets/images/book_icon.gif +0 -0
- data/guides/assets/images/bullet.gif +0 -0
- data/guides/assets/images/chapters_icon.gif +0 -0
- data/guides/assets/images/check_bullet.gif +0 -0
- data/guides/assets/images/credits_pic_blank.gif +0 -0
- data/guides/assets/images/csrf.png +0 -0
- data/guides/assets/images/edge_badge.png +0 -0
- data/guides/assets/images/favicon.ico +0 -0
- data/guides/assets/images/feature_tile.gif +0 -0
- data/guides/assets/images/footer_tile.gif +0 -0
- data/guides/assets/images/fxn.png +0 -0
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/images/getting_started/challenge.png +0 -0
- data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
- data/guides/assets/images/getting_started/form_with_errors.png +0 -0
- data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
- data/guides/assets/images/getting_started/new_article.png +0 -0
- data/guides/assets/images/getting_started/rails_welcome.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
- data/guides/assets/images/grey_bullet.gif +0 -0
- data/guides/assets/images/habtm.png +0 -0
- data/guides/assets/images/has_many.png +0 -0
- data/guides/assets/images/has_many_through.png +0 -0
- data/guides/assets/images/has_one.png +0 -0
- data/guides/assets/images/has_one_through.png +0 -0
- data/guides/assets/images/header_backdrop.png +0 -0
- data/guides/assets/images/header_tile.gif +0 -0
- data/guides/assets/images/i18n/demo_html_safe.png +0 -0
- data/guides/assets/images/i18n/demo_localized_pirate.png +0 -0
- data/guides/assets/images/i18n/demo_translated_en.png +0 -0
- data/guides/assets/images/i18n/demo_translated_pirate.png +0 -0
- data/guides/assets/images/i18n/demo_translation_missing.png +0 -0
- data/guides/assets/images/i18n/demo_untranslated.png +0 -0
- data/guides/assets/images/icons/README +0 -5
- data/guides/assets/images/icons/callouts/1.png +0 -0
- data/guides/assets/images/icons/callouts/10.png +0 -0
- data/guides/assets/images/icons/callouts/11.png +0 -0
- data/guides/assets/images/icons/callouts/12.png +0 -0
- data/guides/assets/images/icons/callouts/13.png +0 -0
- data/guides/assets/images/icons/callouts/14.png +0 -0
- data/guides/assets/images/icons/callouts/15.png +0 -0
- data/guides/assets/images/icons/callouts/2.png +0 -0
- data/guides/assets/images/icons/callouts/3.png +0 -0
- data/guides/assets/images/icons/callouts/4.png +0 -0
- data/guides/assets/images/icons/callouts/5.png +0 -0
- data/guides/assets/images/icons/callouts/6.png +0 -0
- data/guides/assets/images/icons/callouts/7.png +0 -0
- data/guides/assets/images/icons/callouts/8.png +0 -0
- data/guides/assets/images/icons/callouts/9.png +0 -0
- data/guides/assets/images/icons/caution.png +0 -0
- data/guides/assets/images/icons/example.png +0 -0
- data/guides/assets/images/icons/home.png +0 -0
- data/guides/assets/images/icons/important.png +0 -0
- data/guides/assets/images/icons/next.png +0 -0
- data/guides/assets/images/icons/note.png +0 -0
- data/guides/assets/images/icons/prev.png +0 -0
- data/guides/assets/images/icons/tip.png +0 -0
- data/guides/assets/images/icons/up.png +0 -0
- data/guides/assets/images/icons/warning.png +0 -0
- data/guides/assets/images/nav_arrow.gif +0 -0
- data/guides/assets/images/oscardelben.jpg +0 -0
- data/guides/assets/images/polymorphic.png +0 -0
- data/guides/assets/images/radar.png +0 -0
- data/guides/assets/images/rails4_features.png +0 -0
- data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
- data/guides/assets/images/rails_guides_logo.gif +0 -0
- data/guides/assets/images/rails_logo_remix.gif +0 -0
- data/guides/assets/images/session_fixation.png +0 -0
- data/guides/assets/images/tab_grey.gif +0 -0
- data/guides/assets/images/tab_info.gif +0 -0
- data/guides/assets/images/tab_note.gif +0 -0
- data/guides/assets/images/tab_red.gif +0 -0
- data/guides/assets/images/tab_yellow.gif +0 -0
- data/guides/assets/images/tab_yellow.png +0 -0
- data/guides/assets/images/vijaydev.jpg +0 -0
- data/guides/assets/javascripts/guides.js +0 -59
- data/guides/assets/javascripts/jquery.min.js +0 -4
- data/guides/assets/javascripts/responsive-tables.js +0 -43
- data/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js +0 -59
- data/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js +0 -75
- data/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js +0 -59
- data/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js +0 -65
- data/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js +0 -100
- data/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js +0 -97
- data/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js +0 -91
- data/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js +0 -55
- data/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js +0 -41
- data/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js +0 -52
- data/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js +0 -67
- data/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js +0 -52
- data/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js +0 -57
- data/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js +0 -58
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js +0 -72
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js +0 -88
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js +0 -33
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js +0 -74
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js +0 -64
- data/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js +0 -55
- data/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js +0 -94
- data/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js +0 -51
- data/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js +0 -66
- data/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js +0 -56
- data/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js +0 -69
- data/guides/assets/javascripts/syntaxhighlighter/shCore.js +0 -17
- data/guides/assets/stylesheets/fixes.css +0 -16
- data/guides/assets/stylesheets/kindle.css +0 -11
- data/guides/assets/stylesheets/main.css +0 -713
- data/guides/assets/stylesheets/print.css +0 -52
- data/guides/assets/stylesheets/reset.css +0 -43
- data/guides/assets/stylesheets/responsive-tables.css +0 -50
- data/guides/assets/stylesheets/style.css +0 -13
- data/guides/assets/stylesheets/syntaxhighlighter/shCore.css +0 -226
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css +0 -328
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css +0 -331
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css +0 -339
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css +0 -324
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +0 -328
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css +0 -324
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css +0 -324
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css +0 -324
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css +0 -117
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css +0 -120
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css +0 -128
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css +0 -113
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +0 -117
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css +0 -113
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css +0 -113
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css +0 -113
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +0 -116
- data/guides/bug_report_templates/action_controller_gem.rb +0 -47
- data/guides/bug_report_templates/action_controller_master.rb +0 -54
- data/guides/bug_report_templates/active_record_gem.rb +0 -40
- data/guides/bug_report_templates/active_record_master.rb +0 -49
- data/guides/bug_report_templates/generic_gem.rb +0 -15
- data/guides/bug_report_templates/generic_master.rb +0 -26
- data/guides/rails_guides/generator.rb +0 -248
- data/guides/rails_guides/helpers.rb +0 -53
- data/guides/rails_guides/indexer.rb +0 -68
- data/guides/rails_guides/kindle.rb +0 -119
- data/guides/rails_guides/levenshtein.rb +0 -37
- data/guides/rails_guides/markdown/renderer.rb +0 -82
- data/guides/rails_guides/markdown.rb +0 -167
- data/guides/rails_guides.rb +0 -63
- data/guides/source/2_2_release_notes.md +0 -435
- data/guides/source/2_3_release_notes.md +0 -621
- data/guides/source/3_0_release_notes.md +0 -611
- data/guides/source/3_1_release_notes.md +0 -559
- data/guides/source/3_2_release_notes.md +0 -568
- data/guides/source/4_0_release_notes.md +0 -279
- data/guides/source/4_1_release_notes.md +0 -730
- data/guides/source/4_2_release_notes.md +0 -877
- data/guides/source/_license.html.erb +0 -2
- data/guides/source/_welcome.html.erb +0 -23
- data/guides/source/action_controller_overview.md +0 -1192
- data/guides/source/action_mailer_basics.md +0 -757
- data/guides/source/action_view_overview.md +0 -1561
- data/guides/source/active_job_basics.md +0 -339
- data/guides/source/active_model_basics.md +0 -554
- data/guides/source/active_record_basics.md +0 -374
- data/guides/source/active_record_callbacks.md +0 -413
- data/guides/source/active_record_migrations.md +0 -1018
- data/guides/source/active_record_postgresql.md +0 -433
- data/guides/source/active_record_querying.md +0 -1781
- data/guides/source/active_record_validations.md +0 -1179
- data/guides/source/active_support_core_extensions.md +0 -3857
- data/guides/source/active_support_instrumentation.md +0 -488
- data/guides/source/api_documentation_guidelines.md +0 -361
- data/guides/source/asset_pipeline.md +0 -1304
- data/guides/source/association_basics.md +0 -2245
- data/guides/source/autoloading_and_reloading_constants.md +0 -1311
- data/guides/source/caching_with_rails.md +0 -379
- data/guides/source/command_line.md +0 -625
- data/guides/source/configuring.md +0 -1072
- data/guides/source/contributing_to_ruby_on_rails.md +0 -628
- data/guides/source/credits.html.erb +0 -80
- data/guides/source/debugging_rails_applications.md +0 -861
- data/guides/source/development_dependencies_install.md +0 -289
- data/guides/source/documents.yaml +0 -205
- data/guides/source/engines.md +0 -1412
- data/guides/source/form_helpers.md +0 -1024
- data/guides/source/generators.md +0 -676
- data/guides/source/getting_started.md +0 -2086
- data/guides/source/i18n.md +0 -1087
- data/guides/source/index.html.erb +0 -28
- data/guides/source/initialization.md +0 -704
- data/guides/source/kindle/copyright.html.erb +0 -1
- data/guides/source/kindle/layout.html.erb +0 -27
- data/guides/source/kindle/rails_guides.opf.erb +0 -52
- data/guides/source/kindle/toc.html.erb +0 -24
- data/guides/source/kindle/toc.ncx.erb +0 -64
- data/guides/source/kindle/welcome.html.erb +0 -5
- data/guides/source/layout.html.erb +0 -140
- data/guides/source/layouts_and_rendering.md +0 -1227
- data/guides/source/maintenance_policy.md +0 -78
- data/guides/source/nested_model_forms.md +0 -228
- data/guides/source/plugins.md +0 -444
- data/guides/source/rails_application_templates.md +0 -266
- data/guides/source/rails_on_rack.md +0 -336
- data/guides/source/routing.md +0 -1155
- data/guides/source/ruby_on_rails_guides_guidelines.md +0 -127
- data/guides/source/security.md +0 -1024
- data/guides/source/testing.md +0 -1132
- data/guides/source/upgrading_ruby_on_rails.md +0 -1186
- data/guides/source/working_with_javascript_in_rails.md +0 -407
- data/guides/w3c_validator.rb +0 -97
@@ -1,433 +0,0 @@
|
|
1
|
-
Active Record and PostgreSQL
|
2
|
-
============================
|
3
|
-
|
4
|
-
This guide covers PostgreSQL specific usage of Active Record.
|
5
|
-
|
6
|
-
After reading this guide, you will know:
|
7
|
-
|
8
|
-
* How to use PostgreSQL's datatypes.
|
9
|
-
* How to use UUID primary keys.
|
10
|
-
* How to implement full text search with PostgreSQL.
|
11
|
-
* How to back your Active Record models with database views.
|
12
|
-
|
13
|
-
--------------------------------------------------------------------------------
|
14
|
-
|
15
|
-
In order to use the PostgreSQL adapter you need to have at least version 8.2
|
16
|
-
installed. Older versions are not supported.
|
17
|
-
|
18
|
-
To get started with PostgreSQL have a look at the
|
19
|
-
[configuring Rails guide](configuring.html#configuring-a-postgresql-database).
|
20
|
-
It describes how to properly setup Active Record for PostgreSQL.
|
21
|
-
|
22
|
-
Datatypes
|
23
|
-
---------
|
24
|
-
|
25
|
-
PostgreSQL offers a number of specific datatypes. Following is a list of types,
|
26
|
-
that are supported by the PostgreSQL adapter.
|
27
|
-
|
28
|
-
### Bytea
|
29
|
-
|
30
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-binary.html)
|
31
|
-
* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-binarystring.html)
|
32
|
-
|
33
|
-
```ruby
|
34
|
-
# db/migrate/20140207133952_create_documents.rb
|
35
|
-
create_table :documents do |t|
|
36
|
-
t.binary 'payload'
|
37
|
-
end
|
38
|
-
|
39
|
-
# app/models/document.rb
|
40
|
-
class Document < ActiveRecord::Base
|
41
|
-
end
|
42
|
-
|
43
|
-
# Usage
|
44
|
-
data = File.read(Rails.root + "tmp/output.pdf")
|
45
|
-
Document.create payload: data
|
46
|
-
```
|
47
|
-
|
48
|
-
### Array
|
49
|
-
|
50
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/arrays.html)
|
51
|
-
* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-array.html)
|
52
|
-
|
53
|
-
```ruby
|
54
|
-
# db/migrate/20140207133952_create_books.rb
|
55
|
-
create_table :books do |t|
|
56
|
-
t.string 'title'
|
57
|
-
t.string 'tags', array: true
|
58
|
-
t.integer 'ratings', array: true
|
59
|
-
end
|
60
|
-
add_index :books, :tags, using: 'gin'
|
61
|
-
add_index :books, :ratings, using: 'gin'
|
62
|
-
|
63
|
-
# app/models/book.rb
|
64
|
-
class Book < ActiveRecord::Base
|
65
|
-
end
|
66
|
-
|
67
|
-
# Usage
|
68
|
-
Book.create title: "Brave New World",
|
69
|
-
tags: ["fantasy", "fiction"],
|
70
|
-
ratings: [4, 5]
|
71
|
-
|
72
|
-
## Books for a single tag
|
73
|
-
Book.where("'fantasy' = ANY (tags)")
|
74
|
-
|
75
|
-
## Books for multiple tags
|
76
|
-
Book.where("tags @> ARRAY[?]::varchar[]", ["fantasy", "fiction"])
|
77
|
-
|
78
|
-
## Books with 3 or more ratings
|
79
|
-
Book.where("array_length(ratings, 1) >= 3")
|
80
|
-
```
|
81
|
-
|
82
|
-
### Hstore
|
83
|
-
|
84
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/hstore.html)
|
85
|
-
|
86
|
-
```ruby
|
87
|
-
# db/migrate/20131009135255_create_profiles.rb
|
88
|
-
ActiveRecord::Schema.define do
|
89
|
-
create_table :profiles do |t|
|
90
|
-
t.hstore 'settings'
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
# app/models/profile.rb
|
95
|
-
class Profile < ActiveRecord::Base
|
96
|
-
end
|
97
|
-
|
98
|
-
# Usage
|
99
|
-
Profile.create(settings: { "color" => "blue", "resolution" => "800x600" })
|
100
|
-
|
101
|
-
profile = Profile.first
|
102
|
-
profile.settings # => {"color"=>"blue", "resolution"=>"800x600"}
|
103
|
-
|
104
|
-
profile.settings = {"color" => "yellow", "resolution" => "1280x1024"}
|
105
|
-
profile.save!
|
106
|
-
```
|
107
|
-
|
108
|
-
### JSON
|
109
|
-
|
110
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-json.html)
|
111
|
-
* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-json.html)
|
112
|
-
|
113
|
-
```ruby
|
114
|
-
# db/migrate/20131220144913_create_events.rb
|
115
|
-
create_table :events do |t|
|
116
|
-
t.json 'payload'
|
117
|
-
end
|
118
|
-
|
119
|
-
# app/models/event.rb
|
120
|
-
class Event < ActiveRecord::Base
|
121
|
-
end
|
122
|
-
|
123
|
-
# Usage
|
124
|
-
Event.create(payload: { kind: "user_renamed", change: ["jack", "john"]})
|
125
|
-
|
126
|
-
event = Event.first
|
127
|
-
event.payload # => {"kind"=>"user_renamed", "change"=>["jack", "john"]}
|
128
|
-
|
129
|
-
## Query based on JSON document
|
130
|
-
# The -> operator returns the original JSON type (which might be an object), whereas ->> returns text
|
131
|
-
Event.where("payload->>'kind' = ?", "user_renamed")
|
132
|
-
```
|
133
|
-
|
134
|
-
### Range Types
|
135
|
-
|
136
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/rangetypes.html)
|
137
|
-
* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-range.html)
|
138
|
-
|
139
|
-
This type is mapped to Ruby [`Range`](http://www.ruby-doc.org/core-2.1.1/Range.html) objects.
|
140
|
-
|
141
|
-
```ruby
|
142
|
-
# db/migrate/20130923065404_create_events.rb
|
143
|
-
create_table :events do |t|
|
144
|
-
t.daterange 'duration'
|
145
|
-
end
|
146
|
-
|
147
|
-
# app/models/event.rb
|
148
|
-
class Event < ActiveRecord::Base
|
149
|
-
end
|
150
|
-
|
151
|
-
# Usage
|
152
|
-
Event.create(duration: Date.new(2014, 2, 11)..Date.new(2014, 2, 12))
|
153
|
-
|
154
|
-
event = Event.first
|
155
|
-
event.duration # => Tue, 11 Feb 2014...Thu, 13 Feb 2014
|
156
|
-
|
157
|
-
## All Events on a given date
|
158
|
-
Event.where("duration @> ?::date", Date.new(2014, 2, 12))
|
159
|
-
|
160
|
-
## Working with range bounds
|
161
|
-
event = Event.
|
162
|
-
select("lower(duration) AS starts_at").
|
163
|
-
select("upper(duration) AS ends_at").first
|
164
|
-
|
165
|
-
event.starts_at # => Tue, 11 Feb 2014
|
166
|
-
event.ends_at # => Thu, 13 Feb 2014
|
167
|
-
```
|
168
|
-
|
169
|
-
### Composite Types
|
170
|
-
|
171
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/rowtypes.html)
|
172
|
-
|
173
|
-
Currently there is no special support for composite types. They are mapped to
|
174
|
-
normal text columns:
|
175
|
-
|
176
|
-
```sql
|
177
|
-
CREATE TYPE full_address AS
|
178
|
-
(
|
179
|
-
city VARCHAR(90),
|
180
|
-
street VARCHAR(90)
|
181
|
-
);
|
182
|
-
```
|
183
|
-
|
184
|
-
```ruby
|
185
|
-
# db/migrate/20140207133952_create_contacts.rb
|
186
|
-
execute <<-SQL
|
187
|
-
CREATE TYPE full_address AS
|
188
|
-
(
|
189
|
-
city VARCHAR(90),
|
190
|
-
street VARCHAR(90)
|
191
|
-
);
|
192
|
-
SQL
|
193
|
-
create_table :contacts do |t|
|
194
|
-
t.column :address, :full_address
|
195
|
-
end
|
196
|
-
|
197
|
-
# app/models/contact.rb
|
198
|
-
class Contact < ActiveRecord::Base
|
199
|
-
end
|
200
|
-
|
201
|
-
# Usage
|
202
|
-
Contact.create address: "(Paris,Champs-Élysées)"
|
203
|
-
contact = Contact.first
|
204
|
-
contact.address # => "(Paris,Champs-Élysées)"
|
205
|
-
contact.address = "(Paris,Rue Basse)"
|
206
|
-
contact.save!
|
207
|
-
```
|
208
|
-
|
209
|
-
### Enumerated Types
|
210
|
-
|
211
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-enum.html)
|
212
|
-
|
213
|
-
Currently there is no special support for enumerated types. They are mapped as
|
214
|
-
normal text columns:
|
215
|
-
|
216
|
-
```ruby
|
217
|
-
# db/migrate/20131220144913_create_articles.rb
|
218
|
-
execute <<-SQL
|
219
|
-
CREATE TYPE article_status AS ENUM ('draft', 'published');
|
220
|
-
SQL
|
221
|
-
create_table :articles do |t|
|
222
|
-
t.column :status, :article_status
|
223
|
-
end
|
224
|
-
|
225
|
-
# app/models/article.rb
|
226
|
-
class Article < ActiveRecord::Base
|
227
|
-
end
|
228
|
-
|
229
|
-
# Usage
|
230
|
-
Article.create status: "draft"
|
231
|
-
article = Article.first
|
232
|
-
article.status # => "draft"
|
233
|
-
|
234
|
-
article.status = "published"
|
235
|
-
article.save!
|
236
|
-
```
|
237
|
-
|
238
|
-
### UUID
|
239
|
-
|
240
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-uuid.html)
|
241
|
-
* [generator functions](http://www.postgresql.org/docs/9.3/static/uuid-ossp.html)
|
242
|
-
|
243
|
-
|
244
|
-
```ruby
|
245
|
-
# db/migrate/20131220144913_create_revisions.rb
|
246
|
-
create_table :revisions do |t|
|
247
|
-
t.column :identifier, :uuid
|
248
|
-
end
|
249
|
-
|
250
|
-
# app/models/revision.rb
|
251
|
-
class Revision < ActiveRecord::Base
|
252
|
-
end
|
253
|
-
|
254
|
-
# Usage
|
255
|
-
Revision.create identifier: "A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11"
|
256
|
-
|
257
|
-
revision = Revision.first
|
258
|
-
revision.identifier # => "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
|
259
|
-
```
|
260
|
-
|
261
|
-
### Bit String Types
|
262
|
-
|
263
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-bit.html)
|
264
|
-
* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-bitstring.html)
|
265
|
-
|
266
|
-
```ruby
|
267
|
-
# db/migrate/20131220144913_create_users.rb
|
268
|
-
create_table :users, force: true do |t|
|
269
|
-
t.column :settings, "bit(8)"
|
270
|
-
end
|
271
|
-
|
272
|
-
# app/models/device.rb
|
273
|
-
class User < ActiveRecord::Base
|
274
|
-
end
|
275
|
-
|
276
|
-
# Usage
|
277
|
-
User.create settings: "01010011"
|
278
|
-
user = User.first
|
279
|
-
user.settings # => "01010011"
|
280
|
-
user.settings = "0xAF"
|
281
|
-
user.settings # => 10101111
|
282
|
-
user.save!
|
283
|
-
```
|
284
|
-
|
285
|
-
### Network Address Types
|
286
|
-
|
287
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-net-types.html)
|
288
|
-
|
289
|
-
The types `inet` and `cidr` are mapped to Ruby
|
290
|
-
[`IPAddr`](http://www.ruby-doc.org/stdlib-2.1.1/libdoc/ipaddr/rdoc/IPAddr.html)
|
291
|
-
objects. The `macaddr` type is mapped to normal text.
|
292
|
-
|
293
|
-
```ruby
|
294
|
-
# db/migrate/20140508144913_create_devices.rb
|
295
|
-
create_table(:devices, force: true) do |t|
|
296
|
-
t.inet 'ip'
|
297
|
-
t.cidr 'network'
|
298
|
-
t.macaddr 'address'
|
299
|
-
end
|
300
|
-
|
301
|
-
# app/models/device.rb
|
302
|
-
class Device < ActiveRecord::Base
|
303
|
-
end
|
304
|
-
|
305
|
-
# Usage
|
306
|
-
macbook = Device.create(ip: "192.168.1.12",
|
307
|
-
network: "192.168.2.0/24",
|
308
|
-
address: "32:01:16:6d:05:ef")
|
309
|
-
|
310
|
-
macbook.ip
|
311
|
-
# => #<IPAddr: IPv4:192.168.1.12/255.255.255.255>
|
312
|
-
|
313
|
-
macbook.network
|
314
|
-
# => #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
|
315
|
-
|
316
|
-
macbook.address
|
317
|
-
# => "32:01:16:6d:05:ef"
|
318
|
-
```
|
319
|
-
|
320
|
-
### Geometric Types
|
321
|
-
|
322
|
-
* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-geometric.html)
|
323
|
-
|
324
|
-
All geometric types, with the exception of `points` are mapped to normal text.
|
325
|
-
A point is casted to an array containing `x` and `y` coordinates.
|
326
|
-
|
327
|
-
|
328
|
-
UUID Primary Keys
|
329
|
-
-----------------
|
330
|
-
|
331
|
-
NOTE: you need to enable the `uuid-ossp` extension to generate UUIDs.
|
332
|
-
|
333
|
-
```ruby
|
334
|
-
# db/migrate/20131220144913_create_devices.rb
|
335
|
-
enable_extension 'uuid-ossp' unless extension_enabled?('uuid-ossp')
|
336
|
-
create_table :devices, id: :uuid, default: 'uuid_generate_v4()' do |t|
|
337
|
-
t.string :kind
|
338
|
-
end
|
339
|
-
|
340
|
-
# app/models/device.rb
|
341
|
-
class Device < ActiveRecord::Base
|
342
|
-
end
|
343
|
-
|
344
|
-
# Usage
|
345
|
-
device = Device.create
|
346
|
-
device.id # => "814865cd-5a1d-4771-9306-4268f188fe9e"
|
347
|
-
```
|
348
|
-
|
349
|
-
Full Text Search
|
350
|
-
----------------
|
351
|
-
|
352
|
-
```ruby
|
353
|
-
# db/migrate/20131220144913_create_documents.rb
|
354
|
-
create_table :documents do |t|
|
355
|
-
t.string 'title'
|
356
|
-
t.string 'body'
|
357
|
-
end
|
358
|
-
|
359
|
-
execute "CREATE INDEX documents_idx ON documents USING gin(to_tsvector('english', title || ' ' || body));"
|
360
|
-
|
361
|
-
# app/models/document.rb
|
362
|
-
class Document < ActiveRecord::Base
|
363
|
-
end
|
364
|
-
|
365
|
-
# Usage
|
366
|
-
Document.create(title: "Cats and Dogs", body: "are nice!")
|
367
|
-
|
368
|
-
## all documents matching 'cat & dog'
|
369
|
-
Document.where("to_tsvector('english', title || ' ' || body) @@ to_tsquery(?)",
|
370
|
-
"cat & dog")
|
371
|
-
```
|
372
|
-
|
373
|
-
Database Views
|
374
|
-
--------------
|
375
|
-
|
376
|
-
* [view creation](http://www.postgresql.org/docs/9.3/static/sql-createview.html)
|
377
|
-
|
378
|
-
Imagine you need to work with a legacy database containing the following table:
|
379
|
-
|
380
|
-
```
|
381
|
-
rails_pg_guide=# \d "TBL_ART"
|
382
|
-
Table "public.TBL_ART"
|
383
|
-
Column | Type | Modifiers
|
384
|
-
------------+-----------------------------+------------------------------------------------------------
|
385
|
-
INT_ID | integer | not null default nextval('"TBL_ART_INT_ID_seq"'::regclass)
|
386
|
-
STR_TITLE | character varying |
|
387
|
-
STR_STAT | character varying | default 'draft'::character varying
|
388
|
-
DT_PUBL_AT | timestamp without time zone |
|
389
|
-
BL_ARCH | boolean | default false
|
390
|
-
Indexes:
|
391
|
-
"TBL_ART_pkey" PRIMARY KEY, btree ("INT_ID")
|
392
|
-
```
|
393
|
-
|
394
|
-
This table does not follow the Rails conventions at all.
|
395
|
-
Because simple PostgreSQL views are updateable by default,
|
396
|
-
we can wrap it as follows:
|
397
|
-
|
398
|
-
```ruby
|
399
|
-
# db/migrate/20131220144913_create_articles_view.rb
|
400
|
-
execute <<-SQL
|
401
|
-
CREATE VIEW articles AS
|
402
|
-
SELECT "INT_ID" AS id,
|
403
|
-
"STR_TITLE" AS title,
|
404
|
-
"STR_STAT" AS status,
|
405
|
-
"DT_PUBL_AT" AS published_at,
|
406
|
-
"BL_ARCH" AS archived
|
407
|
-
FROM "TBL_ART"
|
408
|
-
WHERE "BL_ARCH" = 'f'
|
409
|
-
SQL
|
410
|
-
|
411
|
-
# app/models/article.rb
|
412
|
-
class Article < ActiveRecord::Base
|
413
|
-
self.primary_key = "id"
|
414
|
-
def archive!
|
415
|
-
update_attribute :archived, true
|
416
|
-
end
|
417
|
-
end
|
418
|
-
|
419
|
-
# Usage
|
420
|
-
first = Article.create! title: "Winter is coming",
|
421
|
-
status: "published",
|
422
|
-
published_at: 1.year.ago
|
423
|
-
second = Article.create! title: "Brace yourself",
|
424
|
-
status: "draft",
|
425
|
-
published_at: 1.month.ago
|
426
|
-
|
427
|
-
Article.count # => 1
|
428
|
-
first.archive!
|
429
|
-
Article.count # => 2
|
430
|
-
```
|
431
|
-
|
432
|
-
NOTE: This application only cares about non-archived `Articles`. A view also
|
433
|
-
allows for conditions so we can exclude the archived `Articles` directly.
|