diff options
Diffstat (limited to 'guides/source')
-rw-r--r-- | guides/source/active_record_postgresql.md | 93 | ||||
-rw-r--r-- | guides/source/active_support_core_extensions.md | 2 | ||||
-rw-r--r-- | guides/source/generators.md | 4 | ||||
-rw-r--r-- | guides/source/migrations.md | 5 | ||||
-rw-r--r-- | guides/source/routing.md | 22 |
5 files changed, 108 insertions, 18 deletions
diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md index ae767769dd..169a48afb9 100644 --- a/guides/source/active_record_postgresql.md +++ b/guides/source/active_record_postgresql.md @@ -12,10 +12,9 @@ It describes how to properly setup Active Record for PostgreSQL. After reading this guide, you will know: - * How to use PostgreSQL's datatypes. -* How to use UUID Primary keys. -* How to implement Full text search with PostgreSQL. +* How to use UUID primary keys. +* How to implement full text search with PostgreSQL. -------------------------------------------------------------------------------- @@ -99,7 +98,7 @@ Profile.create(settings: { "color" => "blue", "resolution" => "800x600" }) profile = Profile.first profile.settings # => {"color"=>"blue", "resolution"=>"800x600"} -profile.settings = {"color" => "yellow", "resulution" => "1280x1024"} +profile.settings = {"color" => "yellow", "resolution" => "1280x1024"} profile.save! ## you need to call _will_change! if you are editing the store in place @@ -291,6 +290,33 @@ user.save! The types `inet` and `cidr` are mapped to Ruby [`IPAddr`](http://www.ruby-doc.org/stdlib-2.1.1/libdoc/ipaddr/rdoc/IPAddr.html) objects. The `macaddr` type is mapped to normal text. +```ruby +# db/migrate/20140508144913_create_devices.rb +create_table(:devices, force: true) do |t| + t.inet 'ip' + t.cidr 'network' + t.macaddr 'address' +end + +# app/models/device.rb +class Device < ActiveRecord::Base +end + +# Usage +macbook = Device.create(ip: "192.168.1.12", + network: "192.168.2.0/24", + address: "32:01:16:6d:05:ef") + +macbook.ip +# => #<IPAddr: IPv4:192.168.1.12/255.255.255.255> + +macbook.network +# => #<IPAddr: IPv4:192.168.2.0/255.255.255.0> + +macbook.address +# => "32:01:16:6d:05:ef" +``` + ### Geometric Types * [type definition](http://www.postgresql.org/docs/9.3/static/datatype-geometric.html) @@ -345,3 +371,62 @@ Document.where("to_tsvector('english', title || ' ' || body) @@ to_tsquery(?)", Views ----- + +* [view creation](http://www.postgresql.org/docs/9.3/static/sql-createview.html) + +Imagine you need to work with a legacy database containing the following table: + +``` +rails_pg_guide=# \d "TBL_ART" + Table "public.TBL_ART" + Column | Type | Modifiers +------------+-----------------------------+------------------------------------------------------------ + INT_ID | integer | not null default nextval('"TBL_ART_INT_ID_seq"'::regclass) + STR_TITLE | character varying | + STR_STAT | character varying | default 'draft'::character varying + DT_PUBL_AT | timestamp without time zone | + BL_ARCH | boolean | default false +Indexes: + "TBL_ART_pkey" PRIMARY KEY, btree ("INT_ID") +``` + +This table does not follow the Rails conventions at all. +Because simple PostgreSQL views are updateable by default, +we can wrap it as follows: + +```ruby +# db/migrate/20131220144913_create_articles_view.rb +execute <<-SQL +CREATE VIEW articles AS + SELECT "INT_ID" AS id, + "STR_TITLE" AS title, + "STR_STAT" AS status, + "DT_PUBL_AT" AS published_at, + "BL_ARCH" AS archived + FROM "TBL_ART" + WHERE "BL_ARCH" = 'f' + SQL + +# app/models/article.rb +class Article < ActiveRecord::Base + self.primary_key = "id" + def archive! + update_attribute :archived, true + end +end + +# Usage +first = Article.create! title: "Winter is coming", + status: "published", + published_at: 1.year.ago +second = Article.create! title: "Brace yourself", + status: "draft", + published_at: 1.month.ago + +Article.count # => 1 +first.archive! +p Article.count # => 2 +``` + +Note: This application only cares about non-archived `Articles`. A view also +allows for conditions so we can exclude the archived `Articles` directly. diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 329db7cf29..8d0d6d260d 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -1106,7 +1106,7 @@ end A model may find it useful to set `:instance_accessor` to `false` as a way to prevent mass-assignment from setting the attribute. -NOTE: Defined in `active_support/core_ext/module/attribute_accessors.rb`. `active_support/core_ext/class/attribute_accessors.rb` is deprecated and will be removed in Ruby on Rails 4.2. +NOTE: Defined in `active_support/core_ext/module/attribute_accessors.rb`. ### Subclasses & Descendants diff --git a/guides/source/generators.md b/guides/source/generators.md index 4a5377c206..a1ba97fd35 100644 --- a/guides/source/generators.md +++ b/guides/source/generators.md @@ -248,7 +248,7 @@ end end ``` -We can try out our new generator by creating a helper for users: +We can try out our new generator by creating a helper for products: ```bash $ rails generate my_helper products @@ -507,7 +507,7 @@ Replaces text inside a file. gsub_file 'name_of_file.rb', 'method.to_be_replaced', 'method.the_replacing_code' ``` -Regular Expressions can be used to make this method more precise. You can also use append_file and prepend_file in the same way to place code at the beginning and end of a file respectively. +Regular Expressions can be used to make this method more precise. You can also use `append_file` and `prepend_file` in the same way to place code at the beginning and end of a file respectively. ### `application` diff --git a/guides/source/migrations.md b/guides/source/migrations.md index c61ccfe94a..fe1a6a4697 100644 --- a/guides/source/migrations.md +++ b/guides/source/migrations.md @@ -902,6 +902,11 @@ schema into a RDBMS other than the one used to create it. Because schema dumps are the authoritative source for your database schema, it is strongly recommended that you check them into source control. +`db/schema.rb` contains the current version number of the database. This +ensures conflicts are going to happen in the case of a merge where both +branches touched the schema. When that happens, solve conflicts manually, +keeping the highest version number of the two. + Active Record and Referential Integrity --------------------------------------- diff --git a/guides/source/routing.md b/guides/source/routing.md index 0783bce442..9dab946c72 100644 --- a/guides/source/routing.md +++ b/guides/source/routing.md @@ -662,7 +662,7 @@ get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/ `:constraints` takes regular expressions with the restriction that regexp anchors can't be used. For example, the following route will not work: ```ruby -get '/:id', to: 'posts#show', constraints: {id: /^\d/} +get '/:id', to: 'posts#show', constraints: { id: /^\d/ } ``` However, note that you don't need to use anchors because all routes are anchored at the start. @@ -676,12 +676,12 @@ get '/:username', to: 'users#show' ### Request-Based Constraints -You can also constrain a route based on any method on the <a href="action_controller_overview.html#the-request-object">Request</a> object that returns a `String`. +You can also constrain a route based on any method on the [Request object](action_controller_overview.html#the-request-object) that returns a `String`. You specify a request-based constraint the same way that you specify a segment constraint: ```ruby -get 'photos', constraints: {subdomain: 'admin'} +get 'photos', constraints: { subdomain: 'admin' } ``` You can also specify constraints in a block form: @@ -694,7 +694,7 @@ namespace :admin do end ``` -NOTE: Request constraints work by calling a method on the <a href="action_controller_overview.html#the-request-object">Request object</a> with the same name as the hash key and then compare the return value with the hash value. Therefore, constraint values should match the corresponding Request object method return type. For example: `constraints: { subdomain: 'api' }` will match an `api` subdomain as expected, however using a symbol `constraints: { subdomain: :api }` will not, because `request.subdomain` returns `'api'` as a String. +NOTE: Request constraints work by calling a method on the [Request object](action_controller_overview.html#the-request-object) with the same name as the hash key and then compare the return value with the hash value. Therefore, constraint values should match the corresponding Request object method return type. For example: `constraints: { subdomain: 'api' }` will match an `api` subdomain as expected, however using a symbol `constraints: { subdomain: :api }` will not, because `request.subdomain` returns `'api'` as a String. ### Advanced Constraints @@ -783,8 +783,8 @@ get '/stories/:name', to: redirect('/posts/%{name}') You can also provide a block to redirect, which receives the symbolized path parameters and the request object: ```ruby -get '/stories/:name', to: redirect {|path_params, req| "/posts/#{path_params[:name].pluralize}" } -get '/stories', to: redirect {|path_params, req| "/posts/#{req.subdomain}" } +get '/stories/:name', to: redirect { |path_params, req| "/posts/#{path_params[:name].pluralize}" } +get '/stories', to: redirect { |path_params, req| "/posts/#{req.subdomain}" } ``` Please note that this redirection is a 301 "Moved Permanently" redirect. Keep in mind that some web browsers or proxy servers will cache this type of redirect, making the old page inaccessible. @@ -793,7 +793,7 @@ In all of these cases, if you don't provide the leading host (`http://www.exampl ### Routing to Rack Applications -Instead of a String like `'posts#index'`, which corresponds to the `index` action in the `PostsController`, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher: +Instead of a String like `'posts#index'`, which corresponds to the `index` action in the `PostsController`, you can specify any [Rack application](rails_on_rack.html) as the endpoint for a matcher: ```ruby match '/application.js', to: Sprockets, via: :all @@ -879,7 +879,7 @@ a warning. You can use the `:constraints` option to specify a required format on the implicit `id`. For example: ```ruby -resources :photos, constraints: {id: /[A-Z][A-Z][0-9]+/} +resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ } ``` This declaration constrains the `:id` parameter to match the supplied regular expression. So, in this case, the router would no longer match `/photos/1` to this route. Instead, `/photos/RR27` would match. @@ -919,7 +919,7 @@ will recognize incoming paths beginning with `/photos` and route the requests to ### Overriding the `new` and `edit` Segments -The `:path_names` option lets you override the automatically-generated "new" and "edit" segments in paths: +The `:path_names` option lets you override the automatically-generated `new` and `edit` segments in paths: ```ruby resources :photos, path_names: { new: 'make', edit: 'change' } @@ -954,7 +954,7 @@ end resources :photos ``` -This will provide route helpers such as `admin_photos_path`, `new_admin_photo_path` etc. +This will provide route helpers such as `admin_photos_path`, `new_admin_photo_path`, etc. To prefix a group of route helpers, use `:as` with `scope`: @@ -982,7 +982,7 @@ This will provide you with URLs such as `/bob/posts/1` and will allow you to ref ### Restricting the Routes Created -By default, Rails creates routes for the seven default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the `:only` and `:except` options to fine-tune this behavior. The `:only` option tells Rails to create only the specified routes: +By default, Rails creates routes for the seven default actions (`index`, `show`, `new`, `create`, `edit`, `update`, and `destroy`) for every RESTful route in your application. You can use the `:only` and `:except` options to fine-tune this behavior. The `:only` option tells Rails to create only the specified routes: ```ruby resources :photos, only: [:index, :show] |