From a4bba9ce8d1e4bfa1eecf6db7d1d2e406f7d980c Mon Sep 17 00:00:00 2001 From: Harshad Sabne Date: Mon, 25 Nov 2013 11:25:13 +0530 Subject: Globalize has moved to a new repository From (svenfuchs/globalize3) to (globalize/globalize) --- guides/source/i18n.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/i18n.md b/guides/source/i18n.md index 6f79b3ddd7..1ad3b6ffd5 100644 --- a/guides/source/i18n.md +++ b/guides/source/i18n.md @@ -101,7 +101,7 @@ This means, that in the `:en` locale, the key _hello_ will map to the _Hello wor The I18n library will use **English** as a **default locale**, i.e. if you don't set a different locale, `:en` will be used for looking up translations. -NOTE: The i18n library takes a **pragmatic approach** to locale keys (after [some discussion](http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en)), including only the _locale_ ("language") part, like `:en`, `:pl`, not the _region_ part, like `:en-US` or `:en-GB`, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as `:cs`, `:th` or `:es` (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the `:en-US` locale you would have $ as a currency symbol, while in `:en-GB`, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a `:en-GB` dictionary. Various [Rails I18n plugins](http://rails-i18n.org/wiki) such as [Globalize3](https://github.com/svenfuchs/globalize3) may help you implement it. +NOTE: The i18n library takes a **pragmatic approach** to locale keys (after [some discussion](http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en)), including only the _locale_ ("language") part, like `:en`, `:pl`, not the _region_ part, like `:en-US` or `:en-GB`, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as `:cs`, `:th` or `:es` (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the `:en-US` locale you would have $ as a currency symbol, while in `:en-GB`, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a `:en-GB` dictionary. Various [Rails I18n plugins](http://rails-i18n.org/wiki) such as [Globalize3](https://github.com/globalize/globalize) may help you implement it. The **translations load path** (`I18n.load_path`) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you. -- cgit v1.2.3 From b58f3a641795e1777aa3e12a853c34ff512acfb9 Mon Sep 17 00:00:00 2001 From: Harshad Sabne Date: Tue, 26 Nov 2013 23:25:34 +0530 Subject: Underscore in markdown should be escaped with backslash [ci skip] In the absence of proper escaping the first link was getting messed up and remaining part of the sentence (2nd link) was not displayed in the rendered markdown on the website though it was displaying correctly in the repository markdown file. --- guides/source/i18n.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/i18n.md b/guides/source/i18n.md index 1ad3b6ffd5..fd77c1b36f 100644 --- a/guides/source/i18n.md +++ b/guides/source/i18n.md @@ -289,7 +289,7 @@ private end ``` -Of course, in a production environment you would need much more robust code, and could use a plugin such as Iain Hecker's [http_accept_language](https://github.com/iain/http_accept_language/tree/master) or even Rack middleware such as Ryan Tomayko's [locale](https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/locale.rb). +Of course, in a production environment you would need much more robust code, and could use a plugin such as Iain Hecker's [http\_accept\_language](https://github.com/iain/http_accept_language/tree/master) or even Rack middleware such as Ryan Tomayko's [locale](https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/locale.rb). #### Using GeoIP (or Similar) Database -- cgit v1.2.3 From 427db6b9d2b35a72f3c017eb19a2e1e800b0a7a3 Mon Sep 17 00:00:00 2001 From: Harshad Sabne Date: Thu, 28 Nov 2013 00:03:51 +0530 Subject: Fix on-site markdown rendering [ci skip] --- guides/source/i18n.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/i18n.md b/guides/source/i18n.md index fd77c1b36f..401b1fb729 100644 --- a/guides/source/i18n.md +++ b/guides/source/i18n.md @@ -902,7 +902,7 @@ Rails uses fixed strings and other localizations, such as format strings and oth #### Action View Helper Methods -* `distance_of_time_in_words` translates and pluralizes its result and interpolates the number of seconds, minutes, hours, and so on. See [datetime.distance_in_words](https://github.com/rails/rails/blob/master/actionview/lib/action_view/locale/en.yml#L4) translations. +* `distance_of_time_in_words` translates and pluralizes its result and interpolates the number of seconds, minutes, hours, and so on. See [datetime.distance\_in\_words](https://github.com/rails/rails/blob/master/actionview/lib/action_view/locale/en.yml#L4) translations. * `datetime_select` and `select_month` use translated month names for populating the resulting select tag. See [date.month_names](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L15) for translations. `datetime_select` also looks up the order option from [date.order](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L18) (unless you pass the option explicitly). All date selection helpers translate the prompt using the translations in the [datetime.prompts](https://github.com/rails/rails/blob/master/actionview/lib/action_view/locale/en.yml#L39) scope if applicable. -- cgit v1.2.3 From abefa2f635c09fc51c0f63058acd0d1a46f30f60 Mon Sep 17 00:00:00 2001 From: Harshad Sabne Date: Fri, 29 Nov 2013 18:56:56 +0530 Subject: Remove Rdoc formatting from markdown [ci skip] Use markdown formatting instead --- guides/source/active_support_core_extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 452ddf01eb..e6cd70b0ce 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -424,7 +424,7 @@ NOTE: Defined in `active_support/core_ext/object/with_options.rb`. ### JSON support -Active Support provides a better implementation of `to_json` than the +json+ gem ordinarily provides for Ruby objects. This is because some classes, like +Hash+, +OrderedHash+, and +Process::Status+ need special handling in order to provide a proper JSON representation. +Active Support provides a better implementation of `to_json` than the `json` gem ordinarily provides for Ruby objects. This is because some classes, like `Hash`, `OrderedHash` and `Process::Status` need special handling in order to provide a proper JSON representation. NOTE: Defined in `active_support/core_ext/object/json.rb`. -- cgit v1.2.3 From f4804fafecdc057988575b4516afe9ca1d5f42fc Mon Sep 17 00:00:00 2001 From: Harshad Sabne Date: Sat, 30 Nov 2013 15:47:25 +0530 Subject: Update security.md Add escape character for correct rendering --- guides/source/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/security.md b/guides/source/security.md index 595cf7c62c..25428998f2 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -290,7 +290,7 @@ NOTE: _Make sure file uploads don't overwrite important files, and process media Many web applications allow users to upload files. _File names, which the user may choose (partly), should always be filtered_ as an attacker could use a malicious file name to overwrite any file on the server. If you store file uploads at /var/www/uploads, and the user enters a file name like "../../../etc/passwd", it may overwrite an important file. Of course, the Ruby interpreter would need the appropriate permissions to do so - one more reason to run web servers, database servers and other programs as a less privileged Unix user. -When filtering user input file names, _don't try to remove malicious parts_. Think of a situation where the web application removes all "../" in a file name and an attacker uses a string such as "....//" - the result will be "../". It is best to use a whitelist approach, which _checks for the validity of a file name with a set of accepted characters_. This is opposed to a blacklist approach which attempts to remove not allowed characters. In case it isn't a valid file name, reject it (or replace not accepted characters), but don't remove them. Here is the file name sanitizer from the [attachment_fu plugin](https://github.com/technoweenie/attachment_fu/tree/master): +When filtering user input file names, _don't try to remove malicious parts_. Think of a situation where the web application removes all "../" in a file name and an attacker uses a string such as "....//" - the result will be "../". It is best to use a whitelist approach, which _checks for the validity of a file name with a set of accepted characters_. This is opposed to a blacklist approach which attempts to remove not allowed characters. In case it isn't a valid file name, reject it (or replace not accepted characters), but don't remove them. Here is the file name sanitizer from the [attachment\_fu plugin](https://github.com/technoweenie/attachment_fu/tree/master): ```ruby def sanitize_filename(filename) -- cgit v1.2.3 From 3ab9d01dd4a096029745c5bdec8c7a232779301b Mon Sep 17 00:00:00 2001 From: Paul Nikitochkin Date: Wed, 17 Jul 2013 11:45:55 +0300 Subject: Add `rake test:all`, `rake test:all:db` to guide [ci skip] --- guides/source/testing.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'guides/source') diff --git a/guides/source/testing.md b/guides/source/testing.md index 2fd0ed209d..d00fcd1f03 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -794,18 +794,23 @@ end Rake Tasks for Running your Tests --------------------------------- -You don't need to set up and run your tests by hand on a test-by-test basis. Rails comes with a number of commands to help in testing. The table below lists all commands that come along in the default Rakefile when you initiate a Rails project. +You don't need to set up and run your tests by hand on a test-by-test basis. +Rails comes with a number of commands to help in testing. +The table below lists all commands that come along in the default Rakefile +when you initiate a Rails project. | Tasks | Description | | ----------------------- | ----------- | -| `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake` as Rails will run all the tests by default| -| `rake test:controllers` | Runs all the controller tests from `test/controllers`| -| `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional`| -| `rake test:helpers` | Runs all the helper tests from `test/helpers`| -| `rake test:integration` | Runs all the integration tests from `test/integration`| -| `rake test:mailers` | Runs all the mailer tests from `test/mailers`| -| `rake test:models` | Runs all the model tests from `test/models`| -| `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit`| +| `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake` as Rails will run all the tests by default | +| `rake test:controllers` | Runs all the controller tests from `test/controllers` | +| `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional` | +| `rake test:helpers` | Runs all the helper tests from `test/helpers` | +| `rake test:integration` | Runs all the integration tests from `test/integration` | +| `rake test:mailers` | Runs all the mailer tests from `test/mailers` | +| `rake test:models` | Runs all the model tests from `test/models` | +| `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit` | +| `rake test:all` | Runs all tests quickly by merging all types and not resetting db | +| `rake test:all:db` | Runs all tests quickly by merging all types and resetting db | Brief Note About `MiniTest` -- cgit v1.2.3 From b13c5013ae2332a6f5425949baa1bb2d916e4aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C4=B1tk=C4=B1=20Ba=C4=9Fdat?= Date: Sun, 1 Dec 2013 04:31:15 +0200 Subject: Update render with a spacer_template [ci skip] --- guides/source/action_view_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md index d19dd11181..d451073567 100644 --- a/guides/source/action_view_overview.md +++ b/guides/source/action_view_overview.md @@ -262,7 +262,7 @@ Rails determines the name of the partial to use by looking at the model name in You can also specify a second partial to be rendered between instances of the main partial by using the `:spacer_template` option: ```erb -<%= render @products, spacer_template: "product_ruler" %> +<%= render partial: @products, spacer_template: "product_ruler" %> ``` Rails will render the `_product_ruler` partial (with no data passed to it) between each pair of `_product` partials. -- cgit v1.2.3 From 28be1a28eaf49dc6d2978d99fe1ac7cd770eb8a3 Mon Sep 17 00:00:00 2001 From: Paul Nikitochkin Date: Sun, 1 Dec 2013 08:01:28 +0200 Subject: Removed redundant field name in the guide Fixes: #13108 [ci skip] --- guides/source/active_record_validations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md index cbd1ac9bdf..efa826e8df 100644 --- a/guides/source/active_record_validations.md +++ b/guides/source/active_record_validations.md @@ -337,7 +337,7 @@ set. In fact, this set can be any enumerable object. ```ruby class Account < ActiveRecord::Base validates :subdomain, exclusion: { in: %w(www us ca jp), - message: "Subdomain %{value} is reserved." } + message: "%{value} is reserved." } end ``` -- cgit v1.2.3 From 41ba51f4850a8cd2fe69789011ac33366366d32f Mon Sep 17 00:00:00 2001 From: Harshad Sabne Date: Sun, 1 Dec 2013 15:07:21 +0530 Subject: Update contributing_to_ruby_on_rails.md Escape hyphen --- guides/source/contributing_to_ruby_on_rails.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md index a6956eb009..8b3ff24ee1 100644 --- a/guides/source/contributing_to_ruby_on_rails.md +++ b/guides/source/contributing_to_ruby_on_rails.md @@ -259,7 +259,7 @@ workflow with the [rails-dev-box](https://github.com/rails/rails-dev-box). As a compromise, test what your code obviously affects, and if the change is not in railties run the whole test suite of the affected component. If all is -green that's enough to propose your contribution. We have [Travis CI](https://travis-ci.org/rails/rails) +green that's enough to propose your contribution. We have [Travis CI](https://travis\-ci.org/rails/rails) as a safety net for catching unexpected breakages elsewhere. -- cgit v1.2.3 From 8700e5f56cc4ef27193140e416a580adbe10785f Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Mon, 2 Dec 2013 02:22:56 +0530 Subject: Use genderless pronouns in security guide. [ci skip] related #49ff20d9b164693ed7fee880b69cc14b141678b3 --- guides/source/security.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'guides/source') diff --git a/guides/source/security.md b/guides/source/security.md index 595cf7c62c..c6c86a2bb9 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -70,7 +70,7 @@ Hence, the cookie serves as temporary authentication for the web application. An * Many cross-site scripting (XSS) exploits aim at obtaining the user's cookie. You'll read more about XSS later. -* Instead of stealing a cookie unknown to the attacker, he fixes a user's session identifier (in the cookie) known to him. Read more about this so-called session fixation later. +* Instead of stealing a cookie unknown to the attacker, they fix a user's session identifier (in the cookie) known to them. Read more about this so-called session fixation later. The main objective of most attackers is to make money. The underground prices for stolen bank login accounts range from $10-$1000 (depending on the available amount of funds), $0.40-$20 for credit card numbers, $1-$8 for online auction site accounts and $4-$30 for email passwords, according to the [Symantec Global Internet Security Threat Report](http://eval.symantec.com/mktginfo/enterprise/white_papers/b-whitepaper_internet_security_threat_report_xiii_04-2008.en-us.pdf). @@ -111,8 +111,8 @@ It works like this: * A user receives credits, the amount is stored in a session (which is a bad idea anyway, but we'll do this for demonstration purposes). * The user buys something. -* His new, lower credit will be stored in the session. -* The dark side of the user forces him to take the cookie from the first step (which he copied) and replace the current cookie in the browser. +* Their new, lower credit will be stored in the session. +* The dark side of the user forces them to take the cookie from the first step (which they copied) and replace the current cookie in the browser. * The user has his credit back. Including a nonce (a random value) in the session solves replay attacks. A nonce is valid only once, and the server has to keep track of all the valid nonces. It gets even more complicated if you have several application servers (mongrels). Storing nonces in a database table would defeat the entire purpose of CookieStore (avoiding accessing the database). @@ -121,14 +121,14 @@ The best _solution against it is not to store this kind of data in a session, bu ### Session Fixation -NOTE: _Apart from stealing a user's session id, the attacker may fix a session id known to him. This is called session fixation._ +NOTE: _Apart from stealing a user's session id, the attacker may fix a session id known to them. This is called session fixation._ ![Session fixation](images/session_fixation.png) This attack focuses on fixing a user's session id known to the attacker, and forcing the user's browser into using this id. It is therefore not necessary for the attacker to steal the session id afterwards. Here is how this attack works: -* The attacker creates a valid session id: He loads the login page of the web application where he wants to fix the session, and takes the session id in the cookie from the response (see number 1 and 2 in the image). -* He possibly maintains the session. Expiring sessions, for example every 20 minutes, greatly reduces the time-frame for attack. Therefore he accesses the web application from time to time in order to keep the session alive. +* The attacker creates a valid session id: They load the login page of the web application where they want to fix the session, and take the session id in the cookie from the response (see number 1 and 2 in the image). +* They possibly maintains the session. Expiring sessions, for example every 20 minutes, greatly reduces the time-frame for attack. Therefore they access the web application from time to time in order to keep the session alive. * Now the attacker will force the user's browser into using this session id (see number 3 in the image). As you may not change a cookie of another domain (because of the same origin policy), the attacker has to run a JavaScript from the domain of the target web application. Injecting the JavaScript code into the application by XSS accomplishes this attack. Here is an example: ``. Read more about XSS and injection later on. * The attacker lures the victim to the infected page with the JavaScript code. By viewing the page, the victim's browser will change the session id to the trap session id. * As the new trap session is unused, the web application will require the user to authenticate. @@ -249,7 +249,7 @@ end The above method can be placed in the `ApplicationController` and will be called when a CSRF token is not present on a non-GET request. -Note that _cross-site scripting (XSS) vulnerabilities bypass all CSRF protections_. XSS gives the attacker access to all elements on a page, so he can read the CSRF security token from a form or directly submit the form. Read more about XSS later. +Note that _cross-site scripting (XSS) vulnerabilities bypass all CSRF protections_. XSS gives the attacker access to all elements on a page, so they can read the CSRF security token from a form or directly submit the form. Read more about XSS later. Redirection and Files --------------------- @@ -258,7 +258,7 @@ Another class of security vulnerabilities surrounds the use of redirection and f ### Redirection -WARNING: _Redirection in a web application is an underestimated cracker tool: Not only can the attacker forward the user to a trap web site, he may also create a self-contained attack._ +WARNING: _Redirection in a web application is an underestimated cracker tool: Not only can the attacker forward the user to a trap web site, they may also create a self-contained attack._ Whenever the user is allowed to pass (parts of) the URL for redirection, it is possibly vulnerable. The most obvious attack would be to redirect users to a fake web application which looks and feels exactly as the original one. This so-called phishing attack works by sending an unsuspicious link in an email to the users, injecting the link by XSS in the web application or putting the link into an external site. It is unsuspicious, because the link starts with the URL to the web application and the URL to the malicious site is hidden in the redirection parameter: http://www.example.com/site/redirect?to= www.attacker.com. Here is an example of a legacy action: @@ -268,7 +268,7 @@ def legacy end ``` -This will redirect the user to the main action if he tried to access a legacy action. The intention was to preserve the URL parameters to the legacy action and pass them to the main action. However, it can be exploited by an attacker if he includes a host key in the URL: +This will redirect the user to the main action if they tried to access a legacy action. The intention was to preserve the URL parameters to the legacy action and pass them to the main action. However, it can be exploited by attacker if they included a host key in the URL: ``` http://www.example.com/site/legacy?param1=xy¶m2=23&host=www.attacker.com @@ -379,7 +379,7 @@ NOTE: _Almost every web application has to deal with authorization and authentic There are a number of authentication plug-ins for Rails available. Good ones, such as the popular [devise](https://github.com/plataformatec/devise) and [authlogic](https://github.com/binarylogic/authlogic), store only encrypted passwords, not plain-text passwords. In Rails 3.1 you can use the built-in `has_secure_password` method which has similar features. -Every new user gets an activation code to activate his account when he gets an e-mail with a link in it. After activating the account, the activation_code columns will be set to NULL in the database. If someone requested an URL like these, he would be logged in as the first activated user found in the database (and chances are that this is the administrator): +Every new user gets an activation code to activate their account when they get an e-mail with a link in it. After activating the account, the activation_code columns will be set to NULL in the database. If someone requested an URL like these, they would be logged in as the first activated user found in the database (and chances are that this is the administrator): ``` http://localhost:3006/user/activate @@ -398,7 +398,7 @@ If the parameter was nil, the resulting SQL query will be SELECT * FROM users WHERE (users.activation_code IS NULL) LIMIT 1 ``` -And thus it found the first user in the database, returned it and logged him in. You can find out more about it in [my blog post](http://www.rorsecurity.info/2007/10/28/restful_authentication-login-security/). _It is advisable to update your plug-ins from time to time_. Moreover, you can review your application to find more flaws like this. +And thus it found the first user in the database, returned it and logged them in. You can find out more about it in [my blog post](http://www.rorsecurity.info/2007/10/28/restful_authentication-login-security/). _It is advisable to update your plug-ins from time to time_. Moreover, you can review your application to find more flaws like this. ### Brute-Forcing Accounts @@ -418,11 +418,11 @@ Many web applications make it easy to hijack user accounts. Why not be different #### Passwords -Think of a situation where an attacker has stolen a user's session cookie and thus may co-use the application. If it is easy to change the password, the attacker will hijack the account with a few clicks. Or if the change-password form is vulnerable to CSRF, the attacker will be able to change the victim's password by luring him to a web page where there is a crafted IMG-tag which does the CSRF. As a countermeasure, _make change-password forms safe against CSRF_, of course. And _require the user to enter the old password when changing it_. +Think of a situation where an attacker has stolen a user's session cookie and thus may co-use the application. If it is easy to change the password, the attacker will hijack the account with a few clicks. Or if the change-password form is vulnerable to CSRF, the attacker will be able to change the victim's password by luring them to a web page where there is a crafted IMG-tag which does the CSRF. As a countermeasure, _make change-password forms safe against CSRF_, of course. And _require the user to enter the old password when changing it_. #### E-Mail -However, the attacker may also take over the account by changing the e-mail address. After he changed it, he will go to the forgotten-password page and the (possibly new) password will be mailed to the attacker's e-mail address. As a countermeasure _require the user to enter the password when changing the e-mail address, too_. +However, the attacker may also take over the account by changing the e-mail address. After they change it, they will go to the forgotten-password page and the (possibly new) password will be mailed to the attacker's e-mail address. As a countermeasure _require the user to enter the password when changing the e-mail address, too_. #### Other @@ -430,12 +430,12 @@ Depending on your web application, there may be more ways to hijack the user's a ### CAPTCHAs -INFO: _A CAPTCHA is a challenge-response test to determine that the response is not generated by a computer. It is often used to protect comment forms from automatic spam bots by asking the user to type the letters of a distorted image. The idea of a negative CAPTCHA is not for a user to prove that he is human, but reveal that a robot is a robot._ +INFO: _A CAPTCHA is a challenge-response test to determine that the response is not generated by a computer. It is often used to protect comment forms from automatic spam bots by asking the user to type the letters of a distorted image. The idea of a negative CAPTCHA is not for a user to prove that they are human, but reveal that a robot is a robot._ But not only spam robots (bots) are a problem, but also automatic login bots. A popular CAPTCHA API is [reCAPTCHA](http://recaptcha.net/) which displays two distorted images of words from old books. It also adds an angled line, rather than a distorted background and high levels of warping on the text as earlier CAPTCHAs did, because the latter were broken. As a bonus, using reCAPTCHA helps to digitize old books. [ReCAPTCHA](https://github.com/ambethia/recaptcha/) is also a Rails plug-in with the same name as the API. You will get two keys from the API, a public and a private key, which you have to put into your Rails environment. After that you can use the recaptcha_tags method in the view, and the verify_recaptcha method in the controller. Verify_recaptcha will return false if the validation fails. -The problem with CAPTCHAs is, they are annoying. Additionally, some visually impaired users have found certain kinds of distorted CAPTCHAs difficult to read. The idea of negative CAPTCHAs is not to ask a user to proof that he is human, but reveal that a spam robot is a bot. +The problem with CAPTCHAs is, they are annoying. Additionally, some visually impaired users have found certain kinds of distorted CAPTCHAs difficult to read. The idea of negative CAPTCHAs is not to ask a user to proof that they are human, but reveal that a spam robot is a bot. Most bots are really dumb, they crawl the web and put their spam into every form's field they can find. Negative CAPTCHAs take advantage of that and include a "honeypot" field in the form which will be hidden from the human user by CSS or JavaScript. @@ -528,7 +528,7 @@ The most common parameter that a user might tamper with, is the id parameter, as @project = Project.find(params[:id]) ``` -This is alright for some web applications, but certainly not if the user is not authorized to view all projects. If the user changes the id to 42, and he is not allowed to see that information, he will have access to it anyway. Instead, _query the user's access rights, too_: +This is alright for some web applications, but certainly not if the user is not authorized to view all projects. If the user changes the id to 42, and they are not allowed to see that information, they will have access to it anyway. Instead, _query the user's access rights, too_: ```ruby @project = @current_user.projects.find(params[:id]) @@ -571,7 +571,7 @@ SQL injection attacks aim at influencing database queries by manipulating web ap Project.where("name = '#{params[:name]}'") ``` -This could be in a search action and the user may enter a project's name that he wants to find. If a malicious user enters ' OR 1 --, the resulting SQL query will be: +This could be in a search action and the user may enter a project's name that they want to find. If a malicious user enters ' OR 1 --, the resulting SQL query will be: ```sql SELECT * FROM projects WHERE name = '' OR 1 --' @@ -888,7 +888,7 @@ HTTP/1.1 302 Moved Temporarily Location: http://www.malicious.tld ``` -So _attack vectors for Header Injection are based on the injection of CRLF characters in a header field._ And what could an attacker do with a false redirection? He could redirect to a phishing site that looks the same as yours, but asks to login again (and sends the login credentials to the attacker). Or he could install malicious software through browser security holes on that site. Rails 2.1.2 escapes these characters for the Location field in the `redirect_to` method. _Make sure you do it yourself when you build other header fields with user input._ +So _attack vectors for Header Injection are based on the injection of CRLF characters in a header field._ And what could an attacker do with a false redirection? They could redirect to a phishing site that looks the same as yours, but ask to login again (and sends the login credentials to the attacker). Or they could install malicious software through browser security holes on that site. Rails 2.1.2 escapes these characters for the Location field in the `redirect_to` method. _Make sure you do it yourself when you build other header fields with user input._ #### Response Splitting -- cgit v1.2.3 From 223ff7949e2ee453329bb1efee64e92b77480cdf Mon Sep 17 00:00:00 2001 From: Tejas Dinkar Date: Mon, 2 Dec 2013 09:24:47 +0530 Subject: [ci skip] Removing some gender sensitive object pronouns --- guides/source/active_support_core_extensions.md | 2 +- guides/source/security.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'guides/source') diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 452ddf01eb..54c1945f0e 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -888,7 +888,7 @@ class User < ActiveRecord::Base end ``` -With that configuration you get a user's name via his profile, `user.profile.name`, but it could be handy to still be able to access such attribute directly: +With that configuration you get a user's name via their profile, `user.profile.name`, but it could be handy to still be able to access such attribute directly: ```ruby class User < ActiveRecord::Base diff --git a/guides/source/security.md b/guides/source/security.md index c6c86a2bb9..c698959a2c 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -113,7 +113,7 @@ It works like this: * The user buys something. * Their new, lower credit will be stored in the session. * The dark side of the user forces them to take the cookie from the first step (which they copied) and replace the current cookie in the browser. -* The user has his credit back. +* The user has their credit back. Including a nonce (a random value) in the session solves replay attacks. A nonce is valid only once, and the server has to keep track of all the valid nonces. It gets even more complicated if you have several application servers (mongrels). Storing nonces in a database table would defeat the entire purpose of CookieStore (avoiding accessing the database). @@ -354,9 +354,9 @@ Refer to the Injection section for countermeasures against XSS. It is _recommend **CSRF** Cross-Site Reference Forgery (CSRF) is a gigantic attack method, it allows the attacker to do everything the administrator or Intranet user may do. As you have already seen above how CSRF works, here are a few examples of what attackers can do in the Intranet or admin interface. -A real-world example is a [router reconfiguration by CSRF](http://www.h-online.com/security/Symantec-reports-first-active-attack-on-a-DSL-router--/news/102352). The attackers sent a malicious e-mail, with CSRF in it, to Mexican users. The e-mail claimed there was an e-card waiting for them, but it also contained an image tag that resulted in a HTTP-GET request to reconfigure the user's router (which is a popular model in Mexico). The request changed the DNS-settings so that requests to a Mexico-based banking site would be mapped to the attacker's site. Everyone who accessed the banking site through that router saw the attacker's fake web site and had his credentials stolen. +A real-world example is a [router reconfiguration by CSRF](http://www.h-online.com/security/Symantec-reports-first-active-attack-on-a-DSL-router--/news/102352). The attackers sent a malicious e-mail, with CSRF in it, to Mexican users. The e-mail claimed there was an e-card waiting for them, but it also contained an image tag that resulted in a HTTP-GET request to reconfigure the user's router (which is a popular model in Mexico). The request changed the DNS-settings so that requests to a Mexico-based banking site would be mapped to the attacker's site. Everyone who accessed the banking site through that router saw the attacker's fake web site and had their credentials stolen. -Another example changed Google Adsense's e-mail address and password by. If the victim was logged into Google Adsense, the administration interface for Google advertisements campaigns, an attacker could change his credentials.
 +Another example changed Google Adsense's e-mail address and password by. If the victim was logged into Google Adsense, the administration interface for Google advertisements campaigns, an attacker could change their credentials.
 Another popular attack is to spam your web application, your blog or forum to propagate malicious XSS. Of course, the attacker has to know the URL structure, but most Rails URLs are quite straightforward or they will be easy to find out, if it is an open-source application's admin interface. The attacker may even do 1,000 lucky guesses by just including malicious IMG-tags which try every possible combination. @@ -426,7 +426,7 @@ However, the attacker may also take over the account by changing the e-mail addr #### Other -Depending on your web application, there may be more ways to hijack the user's account. In many cases CSRF and XSS will help to do so. For example, as in a CSRF vulnerability in [Google Mail](http://www.gnucitizen.org/blog/google-gmail-e-mail-hijack-technique/). In this proof-of-concept attack, the victim would have been lured to a web site controlled by the attacker. On that site is a crafted IMG-tag which results in a HTTP GET request that changes the filter settings of Google Mail. If the victim was logged in to Google Mail, the attacker would change the filters to forward all e-mails to his e-mail address. This is nearly as harmful as hijacking the entire account. As a countermeasure, _review your application logic and eliminate all XSS and CSRF vulnerabilities_. +Depending on your web application, there may be more ways to hijack the user's account. In many cases CSRF and XSS will help to do so. For example, as in a CSRF vulnerability in [Google Mail](http://www.gnucitizen.org/blog/google-gmail-e-mail-hijack-technique/). In this proof-of-concept attack, the victim would have been lured to a web site controlled by the attacker. On that site is a crafted IMG-tag which results in a HTTP GET request that changes the filter settings of Google Mail. If the victim was logged in to Google Mail, the attacker would change the filters to forward all e-mails to their e-mail address. This is nearly as harmful as hijacking the entire account. As a countermeasure, _review your application logic and eliminate all XSS and CSRF vulnerabilities_. ### CAPTCHAs @@ -581,7 +581,7 @@ The two dashes start a comment ignoring everything after it. So the query return #### Bypassing Authorization -Usually a web application includes access control. The user enters his login credentials, the web application tries to find the matching record in the users table. The application grants access when it finds a record. However, an attacker may possibly bypass this check with SQL injection. The following shows a typical database query in Rails to find the first record in the users table which matches the login credentials parameters supplied by the user. +Usually a web application includes access control. The user enters their login credentials and the web application tries to find the matching record in the users table. The application grants access when it finds a record. However, an attacker may possibly bypass this check with SQL injection. The following shows a typical database query in Rails to find the first record in the users table which matches the login credentials parameters supplied by the user. ```ruby User.first("login = '#{params[:name]}' AND password = '#{params[:password]}'") @@ -679,7 +679,7 @@ These examples don't do any harm so far, so let's see how an attacker can steal ``` -For an attacker, of course, this is not useful, as the victim will see his own cookie. The next example will try to load an image from the URL http://www.attacker.com/ plus the cookie. Of course this URL does not exist, so the browser displays nothing. But the attacker can review his web server's access log files to see the victim's cookie. +For an attacker, of course, this is not useful, as the victim will see their own cookie. The next example will try to load an image from the URL http://www.attacker.com/ plus the cookie. Of course this URL does not exist, so the browser displays nothing. But the attacker can review their web server's access log files to see the victim's cookie. ```html -- cgit v1.2.3 From 6f0fb7ba25b288ed8930b117a5db51123e6df582 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Sun, 1 Dec 2013 23:33:54 -0500 Subject: Update API docs guidelines with reference about gender neutral pronouns --- guides/source/api_documentation_guidelines.md | 2 ++ 1 file changed, 2 insertions(+) (limited to 'guides/source') diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md index 98ead9570f..9b3ca6e2a5 100644 --- a/guides/source/api_documentation_guidelines.md +++ b/guides/source/api_documentation_guidelines.md @@ -42,6 +42,8 @@ Spell names correctly: Arel, Test::Unit, RSpec, HTML, MySQL, JavaScript, ERB. Wh Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database". +When using pronouns in reference to a hypothetical person, such as "a user with a session cookie", gender neutral pronouns (they/their/them) should be used. + English ------- -- cgit v1.2.3 From 98af6596a9316f134c92ace8debdfc3b6a2c50de Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Sun, 1 Dec 2013 23:40:17 -0500 Subject: Add examples for gender neutral pronouns --- guides/source/api_documentation_guidelines.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md index 9b3ca6e2a5..ccb51ce73c 100644 --- a/guides/source/api_documentation_guidelines.md +++ b/guides/source/api_documentation_guidelines.md @@ -42,7 +42,13 @@ Spell names correctly: Arel, Test::Unit, RSpec, HTML, MySQL, JavaScript, ERB. Wh Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database". -When using pronouns in reference to a hypothetical person, such as "a user with a session cookie", gender neutral pronouns (they/their/them) should be used. +When using pronouns in reference to a hypothetical person, such as "a user with a session cookie", gender neutral pronouns (they/their/them) should be used. Instead of: + +* he or she... use they. +* him or her... use them. +* his or her... use their. +* his or hers... use theirs. +* himself or herself... use themselves. English ------- -- cgit v1.2.3 From 5b37036b0aa15ef26c65623457d1a2c8408e32d1 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Mon, 2 Dec 2013 00:36:29 -0500 Subject: Update active_record_querying.md he or she => they --- guides/source/active_record_querying.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 94b8453f04..4725e2c8a2 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -436,7 +436,7 @@ to this code: Client.where("orders_count = #{params[:orders]}") ``` -because of argument safety. Putting the variable directly into the conditions string will pass the variable to the database **as-is**. This means that it will be an unescaped variable directly from a user who may have malicious intent. If you do this, you put your entire database at risk because once a user finds out he or she can exploit your database they can do just about anything to it. Never ever put your arguments directly inside the conditions string. +because of argument safety. Putting the variable directly into the conditions string will pass the variable to the database **as-is**. This means that it will be an unescaped variable directly from a user who may have malicious intent. If you do this, you put your entire database at risk because once a user finds out they can exploit your database they can do just about anything to it. Never ever put your arguments directly inside the conditions string. TIP: For more information on the dangers of SQL injection, see the [Ruby on Rails Security Guide](security.html#sql-injection). -- cgit v1.2.3 From ef0f633c66d8eac6612c118c66ccf1b096bd4d3e Mon Sep 17 00:00:00 2001 From: Akshay Vishnoi Date: Mon, 2 Dec 2013 19:35:02 +0530 Subject: Typo and grammatical fixes [ci skip] --- guides/source/2_2_release_notes.md | 2 +- guides/source/action_view_overview.md | 8 ++++---- guides/source/contributing_to_ruby_on_rails.md | 2 +- guides/source/layouts_and_rendering.md | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'guides/source') diff --git a/guides/source/2_2_release_notes.md b/guides/source/2_2_release_notes.md index c11d1240c4..522f628a7e 100644 --- a/guides/source/2_2_release_notes.md +++ b/guides/source/2_2_release_notes.md @@ -366,7 +366,7 @@ Lead Contributor: [Daniel Schierbeck](http://workingwithrails.com/person/5830-da * `Inflector#parameterize` produces a URL-ready version of its input, for use in `to_param`. * `Time#advance` recognizes fractional days and weeks, so you can do `1.7.weeks.ago`, `1.5.hours.since`, and so on. * The included TzInfo library has been upgraded to version 0.3.12. -* `ActiveSuport::StringInquirer` gives you a pretty way to test for equality in strings: `ActiveSupport::StringInquirer.new("abc").abc? => true` +* `ActiveSupport::StringInquirer` gives you a pretty way to test for equality in strings: `ActiveSupport::StringInquirer.new("abc").abc? => true` Railties -------- diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md index d19dd11181..b5f41f2cba 100644 --- a/guides/source/action_view_overview.md +++ b/guides/source/action_view_overview.md @@ -464,7 +464,7 @@ stylesheet_link_tag :monkey # => #### auto_discovery_link_tag -Returns a link tag that browsers and news readers can use to auto-detect an RSS or Atom feed. +Returns a link tag that browsers and feed readers can use to auto-detect an RSS or Atom feed. ```ruby auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "RSS Feed"}) # => @@ -1143,7 +1143,7 @@ Returns a string of option tags for pretty much any country in the world. #### country_select -Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags. +Returns select and option tags for the given object and method, using country_options_for_select to generate the list of option tags. #### option_groups_from_collection_for_select @@ -1242,7 +1242,7 @@ Returns a string of option tags for pretty much any time zone in the world. #### time_zone_select -Return select and option tags for the given object and method, using `time_zone_options_for_select` to generate the list of option tags. +Returns select and option tags for the given object and method, using `time_zone_options_for_select` to generate the list of option tags. ```ruby time_zone_select( "user", "time_zone") @@ -1258,7 +1258,7 @@ date_field("user", "dob") ### FormTagHelper -Provides a number of methods for creating form tags that doesn't rely on an Active Record object assigned to the template like FormHelper does. Instead, you provide the names and values manually. +Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like FormHelper does. Instead, you provide the names and values manually. #### check_box_tag diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md index a6956eb009..814237ba22 100644 --- a/guides/source/contributing_to_ruby_on_rails.md +++ b/guides/source/contributing_to_ruby_on_rails.md @@ -55,7 +55,7 @@ can expect it to be marked "invalid" as soon as it's reviewed. Sometimes, the line between 'bug' and 'feature' is a hard one to draw. Generally, a feature is anything that adds new behavior, while a bug is -anything that fixes already existing behavior that is mis-behaving. Sometimes, +anything that fixes already existing behavior that is misbehaving. Sometimes, the core team will have to make a judgement call. That said, the distinction generally just affects which release your patch will get in to; we love feature submissions! They just won't get backported to maintenance branches. diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md index c6a3449ace..f4dab57aa5 100644 --- a/guides/source/layouts_and_rendering.md +++ b/guides/source/layouts_and_rendering.md @@ -703,7 +703,7 @@ WARNING: The asset tag helpers do _not_ verify the existence of the assets at th #### Linking to Feeds with the `auto_discovery_link_tag` -The `auto_discovery_link_tag` helper builds HTML that most browsers and newsreaders can use to detect the presence of RSS or Atom feeds. It takes the type of the link (`:rss` or `:atom`), a hash of options that are passed through to url_for, and a hash of options for the tag: +The `auto_discovery_link_tag` helper builds HTML that most browsers and feed readers can use to detect the presence of RSS or Atom feeds. It takes the type of the link (`:rss` or `:atom`), a hash of options that are passed through to url_for, and a hash of options for the tag: ```erb <%= auto_discovery_link_tag(:rss, {action: "feed"}, -- cgit v1.2.3 From 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d Mon Sep 17 00:00:00 2001 From: Genadi Samokovarov Date: Sun, 30 Jun 2013 16:45:32 +0300 Subject: Unify cattr and mattr accessors declarations --- guides/source/active_support_core_extensions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'guides/source') diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 54c1945f0e..90bb4ecaf6 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -624,7 +624,7 @@ NOTE: Defined in `active_support/core_ext/module/attr_internal.rb`. #### Module Attributes -The macros `mattr_reader`, `mattr_writer`, and `mattr_accessor` are analogous to the `cattr_*` macros defined for class. Check [Class Attributes](#class-attributes). +The macros `mattr_reader`, `mattr_writer`, and `mattr_accessor` are the same as the `cattr_*` macros defined for class. In fact, the `cattr_*` macros are just aliases for the `mattr_*` macros. Check [Class Attributes](#class-attributes). For example, the dependencies mechanism uses them: @@ -1119,7 +1119,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/class/attribute_accessors.rb`. +NOTE: Defined in `active_support/core_ext/module/attribute_accessors.rb`. `active_support/core_ext/module/attribute_accessors.rb` is deprecated and will be removed in Ruby on Rails 4.2. ### Subclasses & Descendants -- cgit v1.2.3 From 81abcb79476bdfcd25da26d11690104c5e7e538a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 2 Dec 2013 19:25:14 -0200 Subject: Make the release notes consistent [ci skip] Conflicts: guides/source/4_1_release_notes.md --- guides/source/4_1_release_notes.md | 132 ++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 66 deletions(-) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 449c279d39..f278aa9ea5 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -41,26 +41,26 @@ for detailed changes. ### Removals -* Removed `update:application_controller` rake task. +* Removed `update:application_controller` rake task. -* Removed deprecated `Rails.application.railties.engines`. +* Removed deprecated `Rails.application.railties.engines`. -* Removed deprecated threadsafe! from Rails Config. +* Removed deprecated `threadsafe!` from Rails Config. -* Remove deprecated `ActiveRecord::Generators::ActiveModel#update_attributes` in - favor of `ActiveRecord::Generators::ActiveModel#update` +* Removed deprecated `ActiveRecord::Generators::ActiveModel#update_attributes` in + favor of `ActiveRecord::Generators::ActiveModel#update` -* Remove deprecated `config.whiny_nils` option +* Removed deprecated `config.whiny_nils` option -* Removed deprecated rake tasks for running tests: `rake test:uncommitted` and - `rake test:recent`. +* Removed deprecated rake tasks for running tests: `rake test:uncommitted` and + `rake test:recent`. ### Notable changes * `BACKTRACE` environment variable to show unfiltered backtraces for test failures. ([Commit](https://github.com/rails/rails/commit/84eac5dab8b0fe9ee20b51250e52ad7bfea36553)) -* Expose MiddlewareStack#unshift to environment configuration. ([Pull Request](https://github.com/rails/rails/pull/12479)) +* Exposed `MiddlewareStack#unshift` to environment configuration. ([Pull Request](https://github.com/rails/rails/pull/12479)) Action Mailer @@ -72,8 +72,8 @@ for detailed changes. ### Notable changes -* Instrument the generation of Action Mailer messages. The time it takes to - generate a message is written to the log. ([Pull Request](https://github.com/rails/rails/pull/12556)) +* Instrument the generation of Action Mailer messages. The time it takes to + generate a message is written to the log. ([Pull Request](https://github.com/rails/rails/pull/12556)) Active Model @@ -104,32 +104,32 @@ for detailed changes. ### Removals -* Remove deprecated `String#encoding_aware?` core extensions (`core_ext/string/encoding`). +* Removed deprecated `String#encoding_aware?` core extensions (`core_ext/string/encoding`). -* Remove deprecated `Module#local_constant_names` in favor of `Module#local_constants`. +* Removed deprecated `Module#local_constant_names` in favor of `Module#local_constants`. -* Remove deprecated `DateTime.local_offset` in favor of `DateTime.civil_from_fromat`. +* Removed deprecated `DateTime.local_offset` in favor of `DateTime.civil_from_fromat`. -* Remove deprecated `Logger` core extensions (`core_ext/logger.rb`). +* Removed deprecated `Logger` core extensions (`core_ext/logger.rb`). -* Remove deprecated `Time#time_with_datetime_fallback`, `Time#utc_time` and +* Removed deprecated `Time#time_with_datetime_fallback`, `Time#utc_time` and `Time#local_time` in favor of `Time#utc` and `Time#local`. -* Remove deprecated `Hash#diff` with no replacement. +* Removed deprecated `Hash#diff` with no replacement. -* Remove deprecated `Date#to_time_in_current_zone` in favor of `Date#in_time_zone`. +* Removed deprecated `Date#to_time_in_current_zone` in favor of `Date#in_time_zone`. -* Remove deprecated `Proc#bind` with no replacement. +* Removed deprecated `Proc#bind` with no replacement. -* Remove deprecated `Array#uniq_by` and `Array#uniq_by!`, use native +* Removed deprecated `Array#uniq_by` and `Array#uniq_by!`, use native `Array#uniq` and `Array#uniq!` instead. -* Remove deprecated `ActiveSupport::BasicObject`, use +* Removed deprecated `ActiveSupport::BasicObject`, use `ActiveSupport::ProxyObject` instead. -* Remove deprecated `BufferedLogger`, use `ActiveSupport::Logger` instead. +* Removed deprecated `BufferedLogger`, use `ActiveSupport::Logger` instead. -* Remove deprecated `assert_present` and `assert_blank` methods, use `assert +* Removed deprecated `assert_present` and `assert_blank` methods, use `assert object.blank?` and `assert object.present?` instead. ### Deprecations @@ -140,24 +140,24 @@ for detailed changes. ### Notable changes -* Add `ActiveSupport::Testing::TimeHelpers#travel` and `#travel_to`. These -methods change current time to the given time or time difference by stubbing -`Time.now` and -`Date.today`. ([Pull Request](https://github.com/rails/rails/pull/12824)) +* Added `ActiveSupport::Testing::TimeHelpers#travel` and `#travel_to`. These + methods change current time to the given time or time difference by stubbing + `Time.now` and + `Date.today`. ([Pull Request](https://github.com/rails/rails/pull/12824)) * Added `Numeric#in_milliseconds`, like `1.hour.in_milliseconds`, so we can feed them to JavaScript functions like `getTime()`. ([Commit](https://github.com/rails/rails/commit/423249504a2b468d7a273cbe6accf4f21cb0e643)) -* Add `Date#middle_of_day`, `DateTime#middle_of_day` and `Time#middle_of_day` +* Added `Date#middle_of_day`, `DateTime#middle_of_day` and `Time#middle_of_day` methods. Also added `midday`, `noon`, `at_midday`, `at_noon` and `at_middle_of_day` as aliases. ([Pull Request](https://github.com/rails/rails/pull/10879)) -* Add `String#remove(pattern)` as a short-hand for the common pattern of +* Added `String#remove(pattern)` as a short-hand for the common pattern of `String#gsub(pattern,'')`. ([Commit](https://github.com/rails/rails/commit/5da23a3f921f0a4a3139495d2779ab0d3bd4cb5f)) -* Remove 'cow' => 'kine' irregular inflection from default +* Removed 'cow' => 'kine' irregular inflection from default inflections. ([Commit](https://github.com/rails/rails/commit/c300dca9963bda78b8f358dbcb59cabcdc5e1dc9)) Action Pack @@ -169,32 +169,32 @@ for detailed changes. ### Removals -* Remove deprecated Rails application fallback for integration testing, set - `ActionDispatch.test_app` instead. +* Removed deprecated Rails application fallback for integration testing, set + `ActionDispatch.test_app` instead. -* Remove deprecated `page_cache_extension` config. +* Removed deprecated `page_cache_extension` config. -* Remove deprecated constants from Action Controller: +* Removed deprecated constants from Action Controller: - ActionController::AbstractRequest => ActionDispatch::Request - ActionController::Request => ActionDispatch::Request - ActionController::AbstractResponse => ActionDispatch::Response - ActionController::Response => ActionDispatch::Response - ActionController::Routing => ActionDispatch::Routing - ActionController::Integration => ActionDispatch::Integration - ActionController::IntegrationTest => ActionDispatch::IntegrationTest + ActionController::AbstractRequest => ActionDispatch::Request + ActionController::Request => ActionDispatch::Request + ActionController::AbstractResponse => ActionDispatch::Response + ActionController::Response => ActionDispatch::Response + ActionController::Routing => ActionDispatch::Routing + ActionController::Integration => ActionDispatch::Integration + ActionController::IntegrationTest => ActionDispatch::IntegrationTest ### Notable changes * Take a hash with options inside array in `#url_for`. ([Pull Request](https://github.com/rails/rails/pull/9599)) -* Add `session#fetch` method fetch behaves similarly to +* Added `session#fetch` method fetch behaves similarly to [Hash#fetch](http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch), with the exception that the returned value is always saved into the session. ([Pull Request](https://github.com/rails/rails/pull/12692)) -* Separate Action View completely from Action +* Separated Action View completely from Action Pack. ([Pull Request](https://github.com/rails/rails/pull/11032)) @@ -207,33 +207,33 @@ for detailed changes. ### Removals -* Remove deprecated nil-passing to the following `SchemaCache` methods: +* Removed deprecated nil-passing to the following `SchemaCache` methods: `primary_keys`, `tables`, `columns` and `columns_hash`. -* Remove deprecated block filter from `ActiveRecord::Migrator#migrate`. +* Removed deprecated block filter from `ActiveRecord::Migrator#migrate`. -* Remove deprecated String constructor from `ActiveRecord::Migrator`. +* Removed deprecated String constructor from `ActiveRecord::Migrator`. -* Remove deprecated `scope` use without passing a callable object. +* Removed deprecated `scope` use without passing a callable object. -* Remove deprecated `transaction_joinable=` in favor of `begin_transaction` - with `:joinable` option. +* Removed deprecated `transaction_joinable=` in favor of `begin_transaction` + with `d:joinable` option. -* Remove deprecated `decrement_open_transactions`. +* Removed deprecated `decrement_open_transactions`. -* Remove deprecated `increment_open_transactions`. +* Removed deprecated `increment_open_transactions`. -* Remove deprecated `PostgreSQLAdapter#outside_transaction?` - method. You can use `#transaction_open?` instead. +* Removed deprecated `PostgreSQLAdapter#outside_transaction?` + methodd. You can use `#transaction_open?` instead. -* Remove deprecated `ActiveRecord::Fixtures.find_table_name` in favor of +* Removed deprecated `ActiveRecord::Fixtures.find_table_name` in favor of `ActiveRecord::Fixtures.default_fixture_model_name`. * Removed deprecated `columns_for_remove` from `SchemaStatements`. -* Remove deprecated `SchemaStatements#distinct`. +* Removed deprecated `SchemaStatements#distinct`. -* Move deprecated `ActiveRecord::TestCase` into the rails test +* Moved deprecated `ActiveRecord::TestCase` into the rails test suite. The class is no longer public and is only used for internal Rails tests. @@ -256,12 +256,12 @@ for detailed changes. * Removed deprecated options `finder_sql` and `counter_sql` from collection association. -* Remove deprecated `ActiveRecord::Base#connection` method. +* Removed deprecated `ActiveRecord::Base#connection` method. Make sure to access it via the class. -* Remove deprecation warning for `auto_explain_threshold_in_seconds`. +* Removed deprecation warning for `auto_explain_threshold_in_seconds`. -* Remove deprecated `:distinct` option from `Relation#count`. +* Removed deprecated `:distinct` option from `Relation#count`. * Removed deprecated methods `partial_updates`, `partial_updates?` and `partial_updates=`. @@ -272,22 +272,22 @@ for detailed changes. * Remove implicit join references that were deprecated in 4.0. -* Remove `activerecord-deprecated_finders` as a dependency +* Removed `activerecord-deprecated_finders` as a dependency -* Usage of `implicit_readonly` is being removed`. Please use `readonly` method +* Usage of `implicit_readonly` is being removed. Please use `readonly` method explicitly to mark records as `readonly. ([Pull Request](https://github.com/rails/rails/pull/10769)) ### Deprecations -* Deprecate `quoted_locking_column` method, which isn't used anywhere. +* Deprecated `quoted_locking_column` method, which isn't used anywhere. -* Deprecate the delegation of Array bang methods for associations. +* Deprecated the delegation of Array bang methods for associations. To use them, instead first call `#to_a` on the association to access the array to be acted on. ([Pull Request](https://github.com/rails/rails/pull/12129)) -* Deprecate `ConnectionAdapters::SchemaStatements#distinct`, +* Deprecated `ConnectionAdapters::SchemaStatements#distinct`, as it is no longer used by internals. ([Pull Request](https://github.com/rails/rails/pull/10556)) ### Notable changes @@ -308,7 +308,7 @@ for detailed changes. * Added `ActiveRecord::QueryMethods#rewhere` which will overwrite an existing, named where condition. ([Commit](https://github.com/rails/rails/commit/f950b2699f97749ef706c6939a84dfc85f0b05f2)) -* Extend `ActiveRecord::Base#cache_key` to take an optional list of timestamp +* Extended `ActiveRecord::Base#cache_key` to take an optional list of timestamp attributes of which the highest will be used. ([Commit](https://github.com/rails/rails/commit/e94e97ca796c0759d8fcb8f946a3bbc60252d329)) * Added `ActiveRecord::Base#enum` for declaring enum attributes where the values @@ -337,7 +337,7 @@ for detailed changes. connection. This means that calling `inspect`, when the database is missing, will no longer raise an exception. ([Pull Request](https://github.com/rails/rails/pull/11014)) -* Remove column restrictions for `count`, let the database raise if the SQL is +* Removed column restrictions for `count`, let the database raise if the SQL is invalid. ([Pull Request](https://github.com/rails/rails/pull/10710)) * Rails now automatically detects inverse associations. If you do not set the -- cgit v1.2.3 From 016eb65d7e335b82de49f55f1de679e06855d89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 19 Nov 2013 22:20:35 -0200 Subject: :scissors: [ci skip] --- guides/source/configuring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 8ac34c9716..70f521bf51 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -775,7 +775,7 @@ error similar to given below will be thrown. ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5 seconds. The max pool size is currently 5; consider increasing it: ``` -If you get the above error, you might want to increase the size of connection +If you get the above error, you might want to increase the size of connection pool by incrementing the `pool` option in `database.yml` NOTE. If you have enabled `Rails.threadsafe!` mode then there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited amount of connections. -- cgit v1.2.3 From a6dfe5f0249a4825a79407fb15ae42eac0647d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 19 Nov 2013 22:24:38 -0200 Subject: Use alphabetic order [ci skip] --- guides/source/configuring.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'guides/source') diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 70f521bf51..5377b971b9 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -66,6 +66,8 @@ These configuration methods are to be called on a `Rails::Railtie` object, such * `config.action_view.cache_template_loading` controls whether or not templates should be reloaded on each request. Defaults to whatever is set for `config.cache_classes`. +* `config.beginning_of_week` sets the default beginning of week for the application. Accepts a valid week day symbol (e.g. `:monday`). + * `config.cache_store` configures which cache store to use for Rails caching. Options include one of the symbols `:memory_store`, `:file_store`, `:mem_cache_store`, `:null_store`, or an object that implements the cache API. Defaults to `:file_store` if the directory `tmp/cache` exists, and to `:memory_store` otherwise. * `config.colorize_logging` specifies whether or not to use ANSI color codes when logging information. Defaults to true. @@ -129,8 +131,6 @@ numbers. New applications filter out passwords by adding the following `config.f * `config.time_zone` sets the default time zone for the application and enables time zone awareness for Active Record. -* `config.beginning_of_week` sets the default beginning of week for the application. Accepts a valid week day symbol (e.g. `:monday`). - ### Configuring Assets * `config.assets.enabled` a flag that controls whether the asset -- cgit v1.2.3 From 73c1fc531d70dae5faffe01a31445b4fb8a0d951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 19 Nov 2013 22:39:17 -0200 Subject: Add documentation about the Action Dispatch salt configuration [ci skip] --- guides/source/configuring.md | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'guides/source') diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 5377b971b9..5238d4317c 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -329,6 +329,14 @@ The schema dumper adds one additional configuration option: * `config.action_dispatch.tld_length` sets the TLD (top-level domain) length for the application. Defaults to `1`. +* `config.action_dispatch.http_auth_salt` sets the HTTP Auth salt value. Defaults to `'http authentication'`. + +* `config.action_dispatch.signed_cookie_salt` sets the signed cookies salt value. Defaults to `'signed cookie'`. + +* `config.action_dispatch.encrypted_cookie_salt` sets the encrypted cookies salt value. Defaults to `'encrypted cookie'`. + +* `config.action_dispatch.encrypted_signed_cookie_salt` sets the signed encrypted cookies salt value. Defaults to `'signed encrypted cookie'`. + * `ActionDispatch::Callbacks.before` takes a block of code to run before the request. * `ActionDispatch::Callbacks.to_prepare` takes a block to run after `ActionDispatch::Callbacks.before`, but before the request. Runs for every request in `development` mode, but only once for `production` or environments with `cache_classes` set to `true`. -- cgit v1.2.3 From 0638d329c6b5a1d270150c1b8c74e413e98ef3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 19 Nov 2013 22:43:19 -0200 Subject: Wrap 80 columns [ci skip] --- guides/source/configuring.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'guides/source') diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 5238d4317c..59c2594422 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -66,7 +66,8 @@ These configuration methods are to be called on a `Rails::Railtie` object, such * `config.action_view.cache_template_loading` controls whether or not templates should be reloaded on each request. Defaults to whatever is set for `config.cache_classes`. -* `config.beginning_of_week` sets the default beginning of week for the application. Accepts a valid week day symbol (e.g. `:monday`). +* `config.beginning_of_week` sets the default beginning of week for the +application. Accepts a valid week day symbol (e.g. `:monday`). * `config.cache_store` configures which cache store to use for Rails caching. Options include one of the symbols `:memory_store`, `:file_store`, `:mem_cache_store`, `:null_store`, or an object that implements the cache API. Defaults to `:file_store` if the directory `tmp/cache` exists, and to `:memory_store` otherwise. @@ -329,13 +330,17 @@ The schema dumper adds one additional configuration option: * `config.action_dispatch.tld_length` sets the TLD (top-level domain) length for the application. Defaults to `1`. -* `config.action_dispatch.http_auth_salt` sets the HTTP Auth salt value. Defaults to `'http authentication'`. +* `config.action_dispatch.http_auth_salt` sets the HTTP Auth salt value. Defaults +to `'http authentication'`. -* `config.action_dispatch.signed_cookie_salt` sets the signed cookies salt value. Defaults to `'signed cookie'`. +* `config.action_dispatch.signed_cookie_salt` sets the signed cookies salt value. +Defaults to `'signed cookie'`. -* `config.action_dispatch.encrypted_cookie_salt` sets the encrypted cookies salt value. Defaults to `'encrypted cookie'`. +* `config.action_dispatch.encrypted_cookie_salt` sets the encrypted cookies salt +value. Defaults to `'encrypted cookie'`. -* `config.action_dispatch.encrypted_signed_cookie_salt` sets the signed encrypted cookies salt value. Defaults to `'signed encrypted cookie'`. +* `config.action_dispatch.encrypted_signed_cookie_salt` sets the signed +encrypted cookies salt value. Defaults to `'signed encrypted cookie'`. * `ActionDispatch::Callbacks.before` takes a block of code to run before the request. -- cgit v1.2.3 From b0a3d113a306d6bdec1ed13261ef051d367c7160 Mon Sep 17 00:00:00 2001 From: Juanito Fatas Date: Tue, 3 Dec 2013 00:50:47 +0800 Subject: Add number and range field to form helpers article Also wrap surrounding text to 80 chars. [ci skip] Closes #13132 --- guides/source/form_helpers.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'guides/source') diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md index 4b6d8a93f0..26d9a86be0 100644 --- a/guides/source/form_helpers.md +++ b/guides/source/form_helpers.md @@ -154,7 +154,10 @@ make it easier for users to click the inputs. ### Other Helpers of Interest -Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, date fields, time fields, color fields, datetime fields, datetime-local fields, month fields, week fields, URL fields and email fields: +Other form controls worth mentioning are textareas, password fields, +hidden fields, search fields, telephone fields, date fields, time fields, +color fields, datetime fields, datetime-local fields, month fields, week fields, +URL fields, email fields, number fields and range fields: ```erb <%= text_area_tag(:message, "Hi, nice site", size: "24x6") %> @@ -171,6 +174,8 @@ Other form controls worth mentioning are textareas, password fields, hidden fiel <%= email_field(:user, :address) %> <%= color_field(:user, :favorite_color) %> <%= time_field(:task, :started_at) %> +<%= number_field(:product, :price, in: 1.0..20.0, step: 0.5) %> +<%= range_field(:product, :discount, in: 1..100) %> ``` Output: @@ -190,11 +195,20 @@ Output: + + ``` Hidden inputs are not shown to the user but instead hold data like any textual input. Values inside them can be changed with JavaScript. -IMPORTANT: The search, telephone, date, time, color, datetime, datetime-local, month, week, URL, and email inputs are HTML5 controls. If you require your app to have a consistent experience in older browsers, you will need an HTML5 polyfill (provided by CSS and/or JavaScript). There is definitely [no shortage of solutions for this](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills), although a couple of popular tools at the moment are [Modernizr](http://www.modernizr.com/) and [yepnope](http://yepnopejs.com/), which provide a simple way to add functionality based on the presence of detected HTML5 features. +IMPORTANT: The search, telephone, date, time, color, datetime, datetime-local, +month, week, URL, email, number and range inputs are HTML5 controls. +If you require your app to have a consistent experience in older browsers, +you will need an HTML5 polyfill (provided by CSS and/or JavaScript). +There is definitely [no shortage of solutions for this](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills), although a couple of popular tools at the moment are +[Modernizr](http://www.modernizr.com/) and [yepnope](http://yepnopejs.com/), +which provide a simple way to add functionality based on the presence of +detected HTML5 features. TIP: If you're using password input fields (for any purpose), you might want to configure your application to prevent those parameters from being logged. You can learn about this in the [Security Guide](security.html#logging). -- cgit v1.2.3 From f3c2c733362bb17f1d9a128f46ab165f54449d12 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 2 Dec 2013 21:33:31 -0200 Subject: Fix note about class attribute accessors deprecated file [ci skip] --- guides/source/active_support_core_extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 90bb4ecaf6..567c137a6e 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -1119,7 +1119,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/module/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`. `active_support/core_ext/class/attribute_accessors.rb` is deprecated and will be removed in Ruby on Rails 4.2. ### Subclasses & Descendants -- cgit v1.2.3 From 5fdb594f7b95bcaf10930f30a651edab17932fa3 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 2 Dec 2013 21:36:09 -0200 Subject: Remove dead comment from AS extensions guide [ci skip] --- guides/source/active_support_core_extensions.md | 2 -- 1 file changed, 2 deletions(-) (limited to 'guides/source') diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 567c137a6e..2c9cd0df0c 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -2285,8 +2285,6 @@ The defaults for these options can be localized, their keys are: | `:words_connector` | `support.array.words_connector` | | `:last_word_connector` | `support.array.last_word_connector` | -Options `:connector` and `:skip_last_comma` are deprecated. - NOTE: Defined in `active_support/core_ext/array/conversions.rb`. #### `to_formatted_s` -- cgit v1.2.3 From b42d4c407dcaf7ed1621d081aff1dcb1855b22e2 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 2 Dec 2013 21:42:48 -0200 Subject: Remove note about removed local_constant_names method from guides [ci skip] --- guides/source/active_support_core_extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 2c9cd0df0c..a83aee5d43 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -735,7 +735,7 @@ X.local_constants # => [:X1, :X2, :Y] X::Y.local_constants # => [:Y1, :X1] ``` -The names are returned as symbols. (The deprecated method `local_constant_names` returns strings.) +The names are returned as symbols. NOTE: Defined in `active_support/core_ext/module/introspection.rb`. -- cgit v1.2.3 From ddf27acbc285a892842866cde04951cdad52c5c9 Mon Sep 17 00:00:00 2001 From: Victor Costan Date: Sun, 24 Nov 2013 12:52:53 -0500 Subject: Introduce a context for rendering fixtures ERB. Fixture files are passed through an ERB renderer before being read as YAML. The rendering is currently done in the context of the main object, so method definitons leak into other fixtures, and there is no clean place to define fixture helpers. After this commit, the ERB renderer will use a new subclass of ActiveRecord::FixtureSet.context_class each time a fixture is rendered. --- guides/source/4_1_release_notes.md | 4 ++++ guides/source/upgrading_ruby_on_rails.md | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index f278aa9ea5..de29b2e58e 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -348,6 +348,10 @@ for detailed changes. ActiveRecord will now translate aliased attribute names to the actual column name used in the database. ([Pull Request](https://github.com/rails/rails/pull/7839)) +* The ERB in fixture files is no longer evaluated in the context of the main + object. Helper methods used by multiple fixtures should be defined on modules + included in `ActiveRecord::FixtureSet.context_class`. ([Pull Request](https://github.com/rails/rails/pull/13022)) + Credits ------- diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index ef5f6ac024..3fbc913d8b 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -27,6 +27,23 @@ Upgrading from Rails 4.0 to Rails 4.1 NOTE: This section is a work in progress. +### Methods defined in Active Record fixtures + +Rails 4.1 evaluates each fixture's ERB in a separate context, so helper methods +defined in a fixture will not be available in other fixtures. + +Helper methods that are used in multiple fixtures should be defined on modules +included in the newly introduced `ActiveRecord::FixtureSet.context_class`, in +`test_helper.rb`. + +```ruby +class FixtureFileHelpers + def file_sha(path) + Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path))) + end +end +ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers +``` Upgrading from Rails 3.2 to Rails 4.0 ------------------------------------- -- cgit v1.2.3 From eb0402d512a1fb4e65a4d8d3dab3684e9f136b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Tue, 3 Dec 2013 13:23:41 +0100 Subject: Add variants to release notes --- guides/source/4_1_release_notes.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index de29b2e58e..0e3e2037ff 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -3,6 +3,7 @@ Ruby on Rails 4.1 Release Notes Highlights in Rails 4.1: +* Variants * Action View extracted from Action Pack These release notes cover only the major changes. To know about various bug @@ -27,6 +28,38 @@ guide. Major Features -------------- +* Variants + + We often want to render different html/json/xml templates for phones, + tablets, and desktop browsers. Variants make it easy. + + The request variant is a specialization of the request format, like :tablet, + :phone, or :desktop. + + You can set the variant in a before_action: + + ```ruby + request.variant = :tablet if request.user_agent =~ /iPad/ + ``` + + Respond to variants in the action just like you respond to formats: + + ```ruby + respond_to do |format| + format.html do |html| + html.tablet # renders app/views/projects/show.html+tablet.erb + html.phone { extra_setup; render ... } + end + end + ``` + + Provide separate templates for each format and variant: + + ``` + app/views/projects/show.html.erb + app/views/projects/show.html+tablet.erb + app/views/projects/show.html+phone.erb + ``` Documentation ------------- -- cgit v1.2.3 From 3fd0bf48963e67199d774bbd04b7893bdb5cf524 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Sat, 30 Nov 2013 01:54:27 -0800 Subject: Added JSON release notes [ci skip] --- guides/source/4_1_release_notes.md | 35 +++++++++++++++++++++ guides/source/upgrading_ruby_on_rails.md | 54 ++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 0e3e2037ff..97f4e48375 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -137,6 +137,17 @@ for detailed changes. ### Removals +* Removed `MultiJSON` dependency. As a result, `ActiveSupport::JSON.decode` + no longer accepts an options hash for `MultiJSON`. ([Pull Request](https://github.com/rails/rails/pull/10576) / [More Details](upgrading_ruby_on_rails.html#changes-in-json-handling)) + +* Removed support for the `encode_json` hook used for encoding custom objects into + JSON. This feature has been extracted into the [activesupport-json_encoder](https://github.com/rails/activesupport-json_encoder) + gem. + ([Related Pull Request](https://github.com/rails/rails/pull/12183) / + [More Details](upgrading_ruby_on_rails.html#changes-in-json-handling)) + +* Removed deprecated `ActiveSupport::JSON::Variable` with no replacement. + * Removed deprecated `String#encoding_aware?` core extensions (`core_ext/string/encoding`). * Removed deprecated `Module#local_constant_names` in favor of `Module#local_constants`. @@ -171,8 +182,32 @@ for detailed changes. explicitly convert the value into an AS::Duration, i.e. `5.ago` => `5.seconds.ago` ([Pull Request](https://github.com/rails/rails/pull/12389)) +* Deprecated the require path `active_support/core_ext/object/to_json`. Require + `active_support/core_ext/object/json` instead. ([Pull Request](https://github.com/rails/rails/pull/12203)) + +* Deprecated `ActiveSupport::JSON::Encoding::CircularReferenceError`. This feature + has been extracted into the [activesupport-json_encoder](https://github.com/rails/activesupport-json_encoder) + gem. + ([Pull Request](https://github.com/rails/rails/pull/12785) / + [More Details](upgrading_ruby_on_rails.html#changes-in-json-handling)) + +* Deprecated `ActiveSupport.encode_big_decimal_as_string` option. This feature has + been extracetd into the [activesupport-json_encoder](https://github.com/rails/activesupport-json_encoder) + gem. + ([Pull Request](https://github.com/rails/rails/pull/13060) / + [More Details](upgrading_ruby_on_rails.html#changes-in-json-handling)) + ### Notable changes +* `ActiveSupport`'s JSON encoder has been rewritten to take advantage of the + JSON gem rather than doing custom encoding in pure-Ruby. + ([Pull Request](https://github.com/rails/rails/pull/12183) / + [More Details](upgrading_ruby_on_rails.html#changes-in-json-handling)) + +* Improved compatibility with the JSON gem. + ([Pull Request](https://github.com/rails/rails/pull/12862) / + [More Details](upgrading_ruby_on_rails.html#changes-in-json-handling)) + * Added `ActiveSupport::Testing::TimeHelpers#travel` and `#travel_to`. These methods change current time to the given time or time difference by stubbing `Time.now` and diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 3fbc913d8b..8ad7e62789 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -27,6 +27,60 @@ Upgrading from Rails 4.0 to Rails 4.1 NOTE: This section is a work in progress. +### Changes in JSON handling + +The are a few major changes related to JSON handling in Rails 4.1. + +#### MultiJSON removal + +MultiJSON has reached its [end-of-life](https://github.com/rails/rails/pull/10576) +and has been removed from Rails. + +If your application currently depend on MultiJSON directly, you have a few options: + +1. Add 'multi_json' to your Gemfile. Note that this might cease to work in the future + +2. Migrate away from MultiJSON by using `obj.to_json`, and `JSON.parse(str)` instead. + +WARNING: Do not simply replace `MultiJson.dump` and `MultiJson.load` with +`JSON.dump` and `JSON.load`. These JSON gem APIs are meant for serializing and +deserializing arbitrary Ruby objects and are generally [unsafe](http://www.ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-load). + +#### JSON gem compatibility + +Historically, Rails had some compatibility issues with the JSON gem. Using +`JSON.generate` and `JSON.dump` inside a Rails application could produce +unexpected errors. + +Rails 4.1 fixed these issues by isolating its own encoder from the JSON gem. The +JSON gem APIs will function as normal, but they will not have access to any +Rails-specific features. For example: + +```ruby +class FooBar + def as_json(options = nil) + { foo: "bar" } + end +end + +>> FooBar.new.to_json # => "{\"foo\":\"bar\"}" +>> JSON.generate(FooBar.new, quirks_mode: true) # => "\"#\"" +``` + +#### New JSON encoder + +The JSON encoder in Rails 4.1 has been rewritten to take advantage of the JSON +gem. For most applications, this should be a transparent change. However, as +part of the rewrite, the following features have been removed from the encoder: + +1. Circular data structure detection +2. Support for the `encode_json` hook +3. Option to encode `BigDecimal` objects as numbers instead of strings + +If you application depends on one of these features, you can get them back by +adding the [`activesupport-json_encoder`](https://github.com/rails/activesupport-json_encoder) +gem to your Gemfile. + ### Methods defined in Active Record fixtures Rails 4.1 evaluates each fixture's ERB in a separate context, so helper methods -- cgit v1.2.3 From a25cb53939f7625c570a5082a583104f6d74d19a Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 4 Dec 2013 10:00:29 +0100 Subject: minor 4_1_release_notes changes. [ci skip] --- guides/source/4_1_release_notes.md | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 97f4e48375..a8ec40adee 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -28,13 +28,13 @@ guide. Major Features -------------- -* Variants +### Variants We often want to render different html/json/xml templates for phones, - tablets, and desktop browsers. Variants make it easy. + tablets, and desktop browsers. Variants makes it easy. - The request variant is a specialization of the request format, like :tablet, - :phone, or :desktop. + The request variant is a specialization of the request format, like `:tablet`, + `:phone`, or `:desktop`. You can set the variant in a before_action: @@ -254,8 +254,8 @@ for detailed changes. ### Notable changes -* Take a hash with options inside array in - `#url_for`. ([Pull Request](https://github.com/rails/rails/pull/9599)) +* `#url_for` takes a hash with options inside an + array. ([Pull Request](https://github.com/rails/rails/pull/9599)) * Added `session#fetch` method fetch behaves similarly to [Hash#fetch](http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch), @@ -301,29 +301,18 @@ for detailed changes. * Removed deprecated `SchemaStatements#distinct`. -* Moved deprecated `ActiveRecord::TestCase` into the rails test +* Moved deprecated `ActiveRecord::TestCase` into the Rails test suite. The class is no longer public and is only used for internal Rails tests. * Removed support for deprecated option `:restrict` for `:dependent` in associations. -* Removed support for deprecated `delete_sql` in associations. - -* Removed support for deprecated `insert_sql` in associations. - -* Removed support for deprecated `finder_sql` in associations. - -* Removed support for deprecated `counter_sql` in associations. +* Removed support for deprecated `:delete_sql`, `:insert_sql`, `:finder_sql` + and `:counter_sql` options in associations. * Removed deprecated method `type_cast_code` from Column. -* Removed deprecated options `delete_sql` and `insert_sql` from HABTM - association. - -* Removed deprecated options `finder_sql` and `counter_sql` from - collection association. - * Removed deprecated `ActiveRecord::Base#connection` method. Make sure to access it via the class. @@ -342,9 +331,9 @@ for detailed changes. * Removed `activerecord-deprecated_finders` as a dependency -* Usage of `implicit_readonly` is being removed. Please use `readonly` method +* Removed usage of `implicit_readonly`. Please use `readonly` method explicitly to mark records as - `readonly. ([Pull Request](https://github.com/rails/rails/pull/10769)) + `readonly`. ([Pull Request](https://github.com/rails/rails/pull/10769)) ### Deprecations -- cgit v1.2.3 From 828a8f214535e59d709fd4862605902d1cc21632 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 4 Dec 2013 11:54:34 +0100 Subject: add Spring as major feature in the 4.1 release notes. [ci skip] Follow up to #12958. --- guides/source/4_1_release_notes.md | 45 ++++++++++++++++++++++++++++++++ guides/source/upgrading_ruby_on_rails.md | 12 +++++++++ 2 files changed, 57 insertions(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index a8ec40adee..c549c14197 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -4,6 +4,7 @@ Ruby on Rails 4.1 Release Notes Highlights in Rails 4.1: * Variants +* Spring * Action View extracted from Action Pack These release notes cover only the major changes. To know about various bug @@ -61,6 +62,44 @@ Major Features app/views/projects/show.html+phone.erb ``` +### Spring + +New Rails 4.1 applications will ship with "springified" binstubs. This means +that `bin/rails` and `bin/rake` will automatically take advantage preloaded +spring environments. + +**running rake tasks:** +``` +bin/rake routes +``` + +**running tests:** +``` +bin/rake test +bin/rake test test/models +bin/rake test test/models/user_test.rb +``` + +**running a console:** +``` +bin/rails console +``` + +**spring introspection:** +``` +$ bundle exec spring status +Spring is running: + + 1182 spring server | my_app | started 29 mins ago + 3656 spring app | my_app | started 23 secs ago | test mode + 3746 spring app | my_app | started 10 secs ago | development mode +``` + +Have a look at the +[Spring README](https://github.com/jonleighton/spring/blob/master/README.md) to +see a all available features. + + Documentation ------------- @@ -90,6 +129,12 @@ for detailed changes. ### Notable changes +* The [Spring application + preloader](https://github.com/jonleighton/spring) is now installed + by default for new applications. It uses the development group of + the Gemfile, so will not be installed in + production. ([Pull Request](https://github.com/rails/rails/pull/12958)) + * `BACKTRACE` environment variable to show unfiltered backtraces for test failures. ([Commit](https://github.com/rails/rails/commit/84eac5dab8b0fe9ee20b51250e52ad7bfea36553)) diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 8ad7e62789..f9d5332754 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -27,6 +27,18 @@ Upgrading from Rails 4.0 to Rails 4.1 NOTE: This section is a work in progress. +### Spring + +If you want to use Spring as your application preloader you need to: + +1. add `gem 'spring', group: :development` to your `Gemfile`. +2. install spring using `bundle install`. +3. springify your binstubs with `bundle exec spring binstub --all`. + +NOTE: User defined rake tasks will run in the `development` environment by +default. If you want them to run in other environments consult the +[Spring README](https://github.com/jonleighton/spring#rake). + ### Changes in JSON handling The are a few major changes related to JSON handling in Rails 4.1. -- cgit v1.2.3 From bad0386bc0ed4f180e436d605897831430aa50c9 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 4 Dec 2013 12:03:53 +0100 Subject: remove variants paragraph indent in release notes. [ci skip] --- guides/source/4_1_release_notes.md | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index c549c14197..3362f3ae06 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -31,36 +31,36 @@ Major Features ### Variants - We often want to render different html/json/xml templates for phones, - tablets, and desktop browsers. Variants makes it easy. +We often want to render different html/json/xml templates for phones, +tablets, and desktop browsers. Variants makes it easy. - The request variant is a specialization of the request format, like `:tablet`, - `:phone`, or `:desktop`. +The request variant is a specialization of the request format, like `:tablet`, +`:phone`, or `:desktop`. - You can set the variant in a before_action: +You can set the variant in a before_action: - ```ruby - request.variant = :tablet if request.user_agent =~ /iPad/ - ``` +```ruby +request.variant = :tablet if request.user_agent =~ /iPad/ +``` - Respond to variants in the action just like you respond to formats: +Respond to variants in the action just like you respond to formats: - ```ruby - respond_to do |format| - format.html do |html| - html.tablet # renders app/views/projects/show.html+tablet.erb - html.phone { extra_setup; render ... } - end - end - ``` +```ruby +respond_to do |format| + format.html do |html| + html.tablet # renders app/views/projects/show.html+tablet.erb + html.phone { extra_setup; render ... } + end +end +``` - Provide separate templates for each format and variant: +Provide separate templates for each format and variant: - ``` - app/views/projects/show.html.erb - app/views/projects/show.html+tablet.erb - app/views/projects/show.html+phone.erb - ``` +``` +app/views/projects/show.html.erb +app/views/projects/show.html+tablet.erb +app/views/projects/show.html+phone.erb +``` ### Spring @@ -86,6 +86,7 @@ bin/rails console ``` **spring introspection:** + ``` $ bundle exec spring status Spring is running: -- cgit v1.2.3 From ded25a3353245ccd0b688222ff41de3b39557020 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Wed, 4 Dec 2013 07:34:22 -0700 Subject: Formatting, capitalization, and punctuation fixes [ci skip] Second try on this commit. --- guides/source/plugins.md | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'guides/source') diff --git a/guides/source/plugins.md b/guides/source/plugins.md index d0aa2e55a2..8587bd48b2 100644 --- a/guides/source/plugins.md +++ b/guides/source/plugins.md @@ -3,9 +3,9 @@ The Basics of Creating Rails Plugins A Rails plugin is either an extension or a modification of the core framework. Plugins provide: -* a way for developers to share bleeding-edge ideas without hurting the stable code base -* a segmented architecture so that units of code can be fixed or updated on their own release schedule -* an outlet for the core developers so that they don't have to include every cool new feature under the sun +* A way for developers to share bleeding-edge ideas without hurting the stable code base. +* A segmented architecture so that units of code can be fixed or updated on their own release schedule. +* An outlet for the core developers so that they don't have to include every cool new feature under the sun. After reading this guide, you will know: @@ -48,7 +48,7 @@ See usage and options by asking for help: $ rails plugin --help ``` -Testing your newly generated plugin +Testing Your Newly Generated Plugin ----------------------------------- You can navigate to the directory that contains the plugin, run the `bundle install` command @@ -92,7 +92,7 @@ Run `rake` to run the test. This test should fail because we haven't implemented Great - now you are ready to start development. -Then in `lib/yaffle.rb` add `require "yaffle/core_ext"`: +In `lib/yaffle.rb`, add `require "yaffle/core_ext"`: ```ruby # yaffle/lib/yaffle.rb @@ -219,7 +219,7 @@ $ rails generate model Wickwall last_squawk:string last_tweet:string ``` Now you can create the necessary database tables in your testing database by navigating to your dummy app -and migrating the database. First +and migrating the database. First, run: ```bash $ cd test/dummy @@ -245,7 +245,7 @@ end ``` -We will also add code to define the acts_as_yaffle method. +We will also add code to define the `acts_as_yaffle` method. ```ruby # yaffle/lib/yaffle/acts_as_yaffle.rb @@ -286,7 +286,7 @@ You can then return to the root directory (`cd ../..`) of your plugin and rerun ``` -Getting closer... Now we will implement the code of the acts_as_yaffle method to make the tests pass. +Getting closer... Now we will implement the code of the `acts_as_yaffle` method to make the tests pass. ```ruby # yaffle/lib/yaffle/acts_as_yaffle.rb @@ -310,7 +310,7 @@ end ActiveRecord::Base.send :include, Yaffle::ActsAsYaffle ``` -When you run `rake` you should see the tests all pass: +When you run `rake`, you should see the tests all pass: ```bash 5 tests, 5 assertions, 0 failures, 0 errors, 0 skips @@ -390,7 +390,11 @@ Run `rake` one final time and you should see: 7 tests, 7 assertions, 0 failures, 0 errors, 0 skips ``` -NOTE: The use of `write_attribute` to write to the field in model is just one example of how a plugin can interact with the model, and will not always be the right method to use. For example, you could also use `send("#{self.class.yaffle_text_field}=", string.to_squawk)`. +NOTE: The use of `write_attribute` to write to the field in model is just one example of how a plugin can interact with the model, and will not always be the right method to use. For example, you could also use: + +```ruby +send("#{self.class.yaffle_text_field}=", string.to_squawk) +``` Generators ---------- @@ -398,7 +402,7 @@ Generators Generators can be included in your gem simply by creating them in a lib/generators directory of your plugin. More information about the creation of generators can be found in the [Generators Guide](generators.html) -Publishing your Gem +Publishing Your Gem ------------------- Gem plugins currently in development can easily be shared from any Git repository. To share the Yaffle gem with others, simply @@ -411,12 +415,12 @@ gem 'yaffle', git: 'git://github.com/yaffle_watcher/yaffle.git' After running `bundle install`, your gem functionality will be available to the application. When the gem is ready to be shared as a formal release, it can be published to [RubyGems](http://www.rubygems.org). -For more information about publishing gems to RubyGems, see: [Creating and Publishing Your First Ruby Gem](http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html) +For more information about publishing gems to RubyGems, see: [Creating and Publishing Your First Ruby Gem](http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html). RDoc Documentation ------------------ -Once your plugin is stable and you are ready to deploy do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy. +Once your plugin is stable and you are ready to deploy, do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy. The first step is to update the README file with detailed information about how to use your plugin. A few key things to include are: -- cgit v1.2.3 From 2e7756aa2f08b7750939594ba22dc8ff20efc0e8 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 4 Dec 2013 17:45:42 +0100 Subject: mention Active Record enums as major feature for 4.1. [ci skip] --- guides/source/4_1_release_notes.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 3362f3ae06..6cdb28ad50 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -69,11 +69,13 @@ that `bin/rails` and `bin/rake` will automatically take advantage preloaded spring environments. **running rake tasks:** + ``` bin/rake routes ``` **running tests:** + ``` bin/rake test bin/rake test test/models @@ -81,6 +83,7 @@ bin/rake test test/models/user_test.rb ``` **running a console:** + ``` bin/rails console ``` @@ -100,6 +103,26 @@ Have a look at the [Spring README](https://github.com/jonleighton/spring/blob/master/README.md) to see a all available features. +### Active Record enums + +Declare an enum attribute where the values map to integers in the database, but +can be queried by name. + +```ruby +class Conversation < ActiveRecord::Base + enum status: [ :active, :archived ] +end + +conversation.archive! +conversation.active? # => false +conversation.status # => "archived" + +Conversation.archived # => Relation for all archived Conversations +``` + +See +[active_record/enum.rb](https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/enum.rb#L2-L42) +for a detailed write up. Documentation ------------- -- cgit v1.2.3 From 673a8a8dfe595bf9820a7dad7c83e04bfb23162e Mon Sep 17 00:00:00 2001 From: Kuldeep Aggarwal Date: Thu, 5 Dec 2013 00:08:02 +0530 Subject: update guides to new version of rails 3.2.x[ci skip] --- guides/source/upgrading_ruby_on_rails.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'guides/source') diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index f9d5332754..596682bb1f 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -433,7 +433,7 @@ Upgrading from Rails 3.1 to Rails 3.2 If your application is currently on any version of Rails older than 3.1.x, you should upgrade to Rails 3.1 before attempting an update to Rails 3.2. -The following changes are meant for upgrading your application to Rails 3.2.15, +The following changes are meant for upgrading your application to Rails 3.2.16, the last 3.2.x version of Rails. ### Gemfile @@ -441,7 +441,7 @@ the last 3.2.x version of Rails. Make the following changes to your `Gemfile`. ```ruby -gem 'rails', '3.2.15' +gem 'rails', '3.2.16' group :assets do gem 'sass-rails', '~> 3.2.6' -- cgit v1.2.3 From 3eab07416acb99068c68b0b7840048fb646feead Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Wed, 4 Dec 2013 19:23:07 +0100 Subject: Update guides welcome page to point to version 3.2.16 [ci skip] --- guides/source/_welcome.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'guides/source') diff --git a/guides/source/_welcome.html.erb b/guides/source/_welcome.html.erb index 93c177905c..ed2025a75d 100644 --- a/guides/source/_welcome.html.erb +++ b/guides/source/_welcome.html.erb @@ -15,8 +15,8 @@

<% end %>

- The guides for Rails 3.2.x are available at http://guides.rubyonrails.org/v3.2.15/. + The guides for Rails 3.2.x are available at http://guides.rubyonrails.org/v3.2.16/.

- The guides for Rails 2.3.x are available at http://guides.rubyonrails.org/v2.3.11/. + The guides for Rails 2.3.x are available at http://guides.rubyonrails.org/v2.3.18/.

-- cgit v1.2.3 From fe077b50c9ce65c4ac1cc718c34dda45cd24c6fe Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Wed, 4 Dec 2013 20:19:10 +0100 Subject: Remove an extra period As a side not, the period after etc is not always needed http://en.wiktionary.org/wiki/etc --- guides/source/api_documentation_guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md index 98ead9570f..d403de5fd3 100644 --- a/guides/source/api_documentation_guidelines.md +++ b/guides/source/api_documentation_guidelines.md @@ -45,7 +45,7 @@ Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite databa English ------- -Please use American English (color, center, modularize, etc).. See [a list of American and British English spelling differences here](http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences). +Please use American English (color, center, modularize, etc). See [a list of American and British English spelling differences here](http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences). Example Code ------------ -- cgit v1.2.3 From 05a011bd6bb003628c74cd37e02859d0c0f38c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 2 Dec 2013 19:21:16 -0200 Subject: Update the releases notes --- guides/source/4_1_release_notes.md | 1 + 1 file changed, 1 insertion(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 6cdb28ad50..99d2a8c117 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -164,6 +164,7 @@ for detailed changes. * Exposed `MiddlewareStack#unshift` to environment configuration. ([Pull Request](https://github.com/rails/rails/pull/12479)) +* Add `Application#message_verifier` method to return a message verifier. ([Pull Request](https://github.com/rails/rails/pull/12995)) Action Mailer ------------- -- cgit v1.2.3 From f56e51d4e43f257b85cff3e9479564890f1317f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 4 Dec 2013 23:17:18 -0200 Subject: Hightlight message verifier in the release notes [ci skip] --- guides/source/4_1_release_notes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 99d2a8c117..b3cd560de0 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -124,6 +124,17 @@ See [active_record/enum.rb](https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/enum.rb#L2-L42) for a detailed write up. +### Application message verifier. + +Create a message verifier that can be used to generate and verify signed +messages in the application. + +```ruby +message = Rails.application.message_verifier('salt').generate('my sensible data') +Rails.application.message_verifier('salt').verify(message) +# => 'my sensible data' +``` + Documentation ------------- -- cgit v1.2.3 From f83dae831f03969c44e80b1d874b0fd00ddeef8a Mon Sep 17 00:00:00 2001 From: Jashank Jeremy Date: Thu, 5 Dec 2013 15:16:00 +1200 Subject: Rails on Rack: Replace an unpleasant grammatical construct. [ci skip] --- guides/source/rails_on_rack.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md index b42c8fb81b..9c92cf3aea 100644 --- a/guides/source/rails_on_rack.md +++ b/guides/source/rails_on_rack.md @@ -144,7 +144,7 @@ use Rack::ETag run MyApp::Application.routes ``` -Purpose of each of this middlewares is explained in the [Internal Middlewares](#internal-middleware-stack) section. +The default middlewares shown here (and some others) are each summarized in the [Internal Middlewares](#internal-middleware-stack) section, below. ### Configuring Middleware Stack -- cgit v1.2.3 From 64c784f5534bdd18866700f9441d99bcef568c3a Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Thu, 5 Dec 2013 11:33:12 +0100 Subject: end sentences with a `.`. [ci skip] --- guides/source/4_1_release_notes.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index b3cd560de0..f1d73ce82a 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -155,9 +155,9 @@ for detailed changes. * Removed deprecated `threadsafe!` from Rails Config. * Removed deprecated `ActiveRecord::Generators::ActiveModel#update_attributes` in - favor of `ActiveRecord::Generators::ActiveModel#update` + favor of `ActiveRecord::Generators::ActiveModel#update`. -* Removed deprecated `config.whiny_nils` option +* Removed deprecated `config.whiny_nils` option. * Removed deprecated rake tasks for running tests: `rake test:uncommitted` and `rake test:recent`. @@ -173,9 +173,11 @@ for detailed changes. * `BACKTRACE` environment variable to show unfiltered backtraces for test failures. ([Commit](https://github.com/rails/rails/commit/84eac5dab8b0fe9ee20b51250e52ad7bfea36553)) -* Exposed `MiddlewareStack#unshift` to environment configuration. ([Pull Request](https://github.com/rails/rails/pull/12479)) +* Exposed `MiddlewareStack#unshift` to environment + configuration. ([Pull Request](https://github.com/rails/rails/pull/12479)) -* Add `Application#message_verifier` method to return a message verifier. ([Pull Request](https://github.com/rails/rails/pull/12995)) +* Add `Application#message_verifier` method to return a message + verifier. ([Pull Request](https://github.com/rails/rails/pull/12995)) Action Mailer ------------- @@ -404,13 +406,13 @@ for detailed changes. * Removed deprecated methods `partial_updates`, `partial_updates?` and `partial_updates=`. -* Removed deprecated method `scoped` +* Removed deprecated method `scoped`. -* Removed deprecated method `default_scopes?` +* Removed deprecated method `default_scopes?`. * Remove implicit join references that were deprecated in 4.0. -* Removed `activerecord-deprecated_finders` as a dependency +* Removed `activerecord-deprecated_finders` as a dependency. * Removed usage of `implicit_readonly`. Please use `readonly` method explicitly to mark records as -- cgit v1.2.3 From d71c1fc6a7f4a7fcdb84b8c091fb29c53b09dc68 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Thu, 5 Dec 2013 11:40:24 +0100 Subject: add missing CHANGELOG entry for d8c6f52. [ci skip] Discoverd by #13175. --- guides/source/4_1_release_notes.md | 3 +++ 1 file changed, 3 insertions(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index f1d73ce82a..5c50ed83ea 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -325,6 +325,9 @@ for detailed changes. * Removed deprecated `page_cache_extension` config. +* Removed deprecated `ActionController::RecordIdentifier`, use + `ActionView::RecordIdentifier` instead. + * Removed deprecated constants from Action Controller: ActionController::AbstractRequest => ActionDispatch::Request -- cgit v1.2.3 From 53fc2f89f6b06384ac4bb9c52ff2f74f8161a413 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Thu, 5 Dec 2013 17:53:34 +0100 Subject: Using 2.3.11 URL for 2.3.x guides [ci skip] --- guides/source/_welcome.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/_welcome.html.erb b/guides/source/_welcome.html.erb index ed2025a75d..27c53689c4 100644 --- a/guides/source/_welcome.html.erb +++ b/guides/source/_welcome.html.erb @@ -18,5 +18,5 @@ The guides for Rails 3.2.x are available at http://guides.rubyonrails.org/v3.2.16/.

- The guides for Rails 2.3.x are available at http://guides.rubyonrails.org/v2.3.18/. + The guides for Rails 2.3.x are available at http://guides.rubyonrails.org/v2.3.11/.

-- cgit v1.2.3 From 71a7b1f1d4364870905746685d76bbaa3072deb9 Mon Sep 17 00:00:00 2001 From: Prashant Sahni Date: Fri, 6 Dec 2013 11:47:22 +0530 Subject: capitalize words starting after numbered list to maintain consistency [ci skip] --- guides/source/upgrading_ruby_on_rails.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'guides/source') diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 596682bb1f..de06ab291f 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -31,9 +31,9 @@ NOTE: This section is a work in progress. If you want to use Spring as your application preloader you need to: -1. add `gem 'spring', group: :development` to your `Gemfile`. -2. install spring using `bundle install`. -3. springify your binstubs with `bundle exec spring binstub --all`. +1. Add `gem 'spring', group: :development` to your `Gemfile`. +2. Install spring using `bundle install`. +3. Springify your binstubs with `bundle exec spring binstub --all`. NOTE: User defined rake tasks will run in the `development` environment by default. If you want them to run in other environments consult the -- cgit v1.2.3 From a7713765d9bb3d64b1640f236c16e68ab4ea95c3 Mon Sep 17 00:00:00 2001 From: Juanito Fatas Date: Sat, 7 Dec 2013 02:04:50 +0800 Subject: Some improvements on building nested forms. [ci skip] --- guides/source/form_helpers.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'guides/source') diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md index 26d9a86be0..e8279b9c0c 100644 --- a/guides/source/form_helpers.md +++ b/guides/source/form_helpers.md @@ -859,7 +859,7 @@ end This creates an `addresses_attributes=` method on `Person` that allows you to create, update and (optionally) destroy addresses. -### Building the Form +### Nested Forms The following form allows a user to create a `Person` and its associated addresses. @@ -882,16 +882,18 @@ The following form allows a user to create a `Person` and its associated address ``` -When an association accepts nested attributes `fields_for` renders its block once for every element of the association. In particular, if a person has no addresses it renders nothing. A common pattern is for the controller to build one or more empty children so that at least one set of fields is shown to the user. The example below would result in 3 sets of address fields being rendered on the new person form. +When an association accepts nested attributes `fields_for` renders its block once for every element of the association. In particular, if a person has no addresses it renders nothing. A common pattern is for the controller to build one or more empty children so that at least one set of fields is shown to the user. The example below would result in 2 sets of address fields being rendered on the new person form. ```ruby def new @person = Person.new - 3.times { @person.addresses.build} + 2.times { @person.addresses.build} end ``` -`fields_for` yields a form builder that names parameters in the format expected the accessor generated by `accepts_nested_attributes_for`. For example when creating a user with 2 addresses, the submitted parameters would look like +The `fields_for` yields a form builder. The parameters' name will be what +`accepts_nested_attributes_for` expects. For example when creating a user with +2 addresses, the submitted parameters would look like: ```ruby { @@ -913,7 +915,7 @@ end The keys of the `:addresses_attributes` hash are unimportant, they need merely be different for each address. -If the associated object is already saved, `fields_for` autogenerates a hidden input with the `id` of the saved record. You can disable this by passing `include_id: false` to `fields_for`. You may wish to do this if the autogenerated input is placed in a location where an input tag is not valid HTML or when using an ORM where children do not have an id. +If the associated object is already saved, `fields_for` autogenerates a hidden input with the `id` of the saved record. You can disable this by passing `include_id: false` to `fields_for`. You may wish to do this if the autogenerated input is placed in a location where an input tag is not valid HTML or when using an ORM where children do not have an `id`. ### The Controller @@ -944,7 +946,9 @@ class Person < ActiveRecord::Base end ``` -If the hash of attributes for an object contains the key `_destroy` with a value of '1' or 'true' then the object will be destroyed. This form allows users to remove addresses: +If the hash of attributes for an object contains the key `_destroy` with a value +of `1` or `true` then the object will be destroyed. This form allows users to +remove addresses: ```erb <%= form_for @person do |f| %> @@ -952,7 +956,7 @@ If the hash of attributes for an object contains the key `_destroy` with a value
    <%= f.fields_for :addresses do |addresses_form| %>
  • - <%= check_box :_destroy%> + <%= addresses_form.check_box :_destroy%> <%= addresses_form.label :kind %> <%= addresses_form.text_field :kind %> ... -- cgit v1.2.3 From 68abbac2fc6ef8808e1788be9c4f41581674d17f Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Wed, 11 Dec 2013 04:57:39 -0800 Subject: Warn about using `return` inside inline callback blocks [ci skip] Closes #12981 --- guides/source/upgrading_ruby_on_rails.md | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'guides/source') diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index de06ab291f..9be48acb12 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -93,6 +93,39 @@ If you application depends on one of these features, you can get them back by adding the [`activesupport-json_encoder`](https://github.com/rails/activesupport-json_encoder) gem to your Gemfile. +### Usage of `return` within inline callback blocks + +Previously, Rails allowed you to `return` from an inline callback block: + +```ruby +class ReadOnlyModel < ActiveRecord::Base + before_save { return false } +end +``` + +This behaviour was never intentionally supported. Due to a change in the internals +of `ActiveSupport::Callbacks`, this is no longer allowed in Rails 4.1. Using a +`return` statement in an inline callback block will cause a `LocalJumpError` to +be raised when the callback is executed. If you need to use `return` statements +in your callbacks, it is recommended that you explicitly define them as methods +and pass the method name as a symbol instead: + +```ruby +class ReadOnlyModel < ActiveRecord::Base + before_save :before_save_callback + + private + def before_save_callback + return false + end +end +``` + +This change applies to most places in Rails where callbacks are used, including +Active Record and Active Model callbacks, as well as "filters" in Action +Controller (e.g. `before_action`). See [this pull request](https://github.com/rails/rails/pull/13271) +for more details. + ### Methods defined in Active Record fixtures Rails 4.1 evaluates each fixture's ERB in a separate context, so helper methods -- cgit v1.2.3 From 10fffd7ae67a7960491f21bd845e19e40cc3ec9a Mon Sep 17 00:00:00 2001 From: Aayush khandelwal Date: Thu, 12 Dec 2013 12:55:35 +0530 Subject: typos rectified lifecycle => life cycle --- guides/source/active_record_callbacks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md index 863da3be72..ece18a0a53 100644 --- a/guides/source/active_record_callbacks.md +++ b/guides/source/active_record_callbacks.md @@ -55,7 +55,7 @@ class User < ActiveRecord::Base end ``` -Callbacks can also be registered to only fire on certain lifecycle events: +Callbacks can also be registered to only fire on certain life cycle events: ```ruby class User < ActiveRecord::Base -- cgit v1.2.3 From bdbb5e3a4210017ab6b984adf11bbae710db7319 Mon Sep 17 00:00:00 2001 From: Kuldeep Aggarwal Date: Mon, 25 Nov 2013 18:14:13 +0530 Subject: [ci skip] added after_touch callback documentation [ci skip] added more explanation for `after_touch` callback --- guides/source/active_record_callbacks.md | 49 ++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'guides/source') diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md index ac5e8ffc0c..6cd7848f68 100644 --- a/guides/source/active_record_callbacks.md +++ b/guides/source/active_record_callbacks.md @@ -141,6 +141,55 @@ You have initialized an object! => # ``` +### `after_touch` + +The `after_touch` callback will be called whenever an Active Record object is touched. + +```ruby +class User < ActiveRecord::Base + after_touch do |user| + puts "You have touched an object" + end +end + +>> u = User.create(name: 'Kuldeep') +=> # + +>> u.touch +You have touched an object +=> true +``` + +It can be used along with `belongs_to`: + +```ruby +class Employee < ActiveRecord::Base + belongs_to :company, touch: true + after_touch do + puts 'An Employee was touched' + end +end + +class Company < ActiveRecord::Base + has_many :employees + after_touch :log_when_employees_or_company_touched + + private + def log_when_employees_or_company_touched + puts 'Employee/Company was touched' + end +end + +>> @employee = Employee.last +=> # + +# triggers @employee.company.touch +>> @employee.touch +Employee/Company was touched +An Employee was touched +=> true +``` + Running Callbacks ----------------- -- cgit v1.2.3 From 3ce9563d42cbec3db69ac31161532460b84abe3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Thu, 12 Dec 2013 11:02:06 +0100 Subject: Variants inline syntax documentation [ci skip] * Extend method documentation * Mention it in actionpack/CHANGELOG * Update release notes --- guides/source/4_1_release_notes.md | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 5c50ed83ea..3126f4e0e1 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -62,6 +62,16 @@ app/views/projects/show.html+tablet.erb app/views/projects/show.html+phone.erb ``` +You can also simplify the variants definition using the inline syntax: + +```ruby +respond_to do |format| + format.js { render "trash" } + format.html.phone { redirect_to progress_path } + format.html.none { render "trash" } +end +``` + ### Spring New Rails 4.1 applications will ship with "springified" binstubs. This means -- cgit v1.2.3 From 5fccd77b6c71e26fcbf879657c1f532999171900 Mon Sep 17 00:00:00 2001 From: Akshay Vishnoi Date: Thu, 12 Dec 2013 18:28:34 +0530 Subject: Spelling and Grammar checks --- guides/source/credits.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/credits.html.erb b/guides/source/credits.html.erb index 5beae9c29b..7c6858fa2c 100644 --- a/guides/source/credits.html.erb +++ b/guides/source/credits.html.erb @@ -76,5 +76,5 @@ Oscar Del Ben is a software engineer at Wi <% end %> <%= author('Akshay Surve', 'startupjockey', 'akshaysurve.jpg') do %> - Akshay Surve is the Founder at DeltaX, hackathon specialist, a midnight code junkie and ocassionally writes prose. You can connect with him on Twitter, Linkedin, Personal Blog or Quora. + Akshay Surve is the Founder at DeltaX, hackathon specialist, a midnight code junkie and occasionally writes prose. You can connect with him on Twitter, Linkedin, Personal Blog or Quora. <% end %> -- cgit v1.2.3 From 6814c78b6793f4bee4278daa8b6dc5e269b2f06a Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 12 Dec 2013 21:20:51 +0100 Subject: copy-edits 68abbac [ci skip] * Rewording to avoid "you"s. * Suggest as first natural alternative to refactor the block to evaluate to the returned value. * Removes the quotes around "filters", since that is a common work in our jargon. --- guides/source/upgrading_ruby_on_rails.md | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'guides/source') diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 9be48acb12..ca5623bf73 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -95,24 +95,34 @@ gem to your Gemfile. ### Usage of `return` within inline callback blocks -Previously, Rails allowed you to `return` from an inline callback block: +Previously, Rails allowed inline callback blocks to use `return` this way: ```ruby class ReadOnlyModel < ActiveRecord::Base - before_save { return false } + before_save { return false } # BAD end ``` This behaviour was never intentionally supported. Due to a change in the internals of `ActiveSupport::Callbacks`, this is no longer allowed in Rails 4.1. Using a -`return` statement in an inline callback block will cause a `LocalJumpError` to -be raised when the callback is executed. If you need to use `return` statements -in your callbacks, it is recommended that you explicitly define them as methods -and pass the method name as a symbol instead: +`return` statement in an inline callback block causes a `LocalJumpError` to +be raised when the callback is executed. + +Inline callback blocks using `return` can be refactored to evaluate to the +returned value: + +```ruby +class ReadOnlyModel < ActiveRecord::Base + before_save { false } # GOOD +end +``` + +Alternatively, if `return` is preferred it is recommended to explicitly define +a method: ```ruby class ReadOnlyModel < ActiveRecord::Base - before_save :before_save_callback + before_save :before_save_callback # GOOD private def before_save_callback @@ -122,9 +132,11 @@ end ``` This change applies to most places in Rails where callbacks are used, including -Active Record and Active Model callbacks, as well as "filters" in Action -Controller (e.g. `before_action`). See [this pull request](https://github.com/rails/rails/pull/13271) -for more details. +Active Record and Active Model callbacks, as well as filters in Action +Controller (e.g. `before_action`). + +See [this pull request](https://github.com/rails/rails/pull/13271) for more +details. ### Methods defined in Active Record fixtures -- cgit v1.2.3 From a176bd095c3cba498369870681695bb29a68f0f9 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 12 Dec 2013 21:48:33 +0100 Subject: docs guidelines: recommends wording in a way that avoids "you"s and "your"s --- guides/source/api_documentation_guidelines.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md index ccb51ce73c..31ef18d21e 100644 --- a/guides/source/api_documentation_guidelines.md +++ b/guides/source/api_documentation_guidelines.md @@ -42,7 +42,21 @@ Spell names correctly: Arel, Test::Unit, RSpec, HTML, MySQL, JavaScript, ERB. Wh Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database". -When using pronouns in reference to a hypothetical person, such as "a user with a session cookie", gender neutral pronouns (they/their/them) should be used. Instead of: +Prefer wordings that avoid "you"s and "your"s. For example, instead of + +```markdown +If you need to use `return` statements in your callbacks, it is recommended that you explicitly define them as methods. +``` + +use this style: + +```markdown +If `return` is needed it is recommended to explicitly define a method. +``` + +That said, when using pronouns in reference to a hypothetical person, such as "a +user with a session cookie", gender neutral pronouns (they/their/them) should be +used. Instead of: * he or she... use they. * him or her... use them. -- cgit v1.2.3 From 6353ea47464b708faaef01a27531915625b93439 Mon Sep 17 00:00:00 2001 From: Afshin Mokhtari Date: Thu, 12 Dec 2013 17:52:18 -0500 Subject: fix grammatical error --- guides/source/getting_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index b57441b1c3..279a977f6f 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -398,7 +398,7 @@ If you refresh now, you'll get a new error: This error indicates that Rails cannot find the `new` action inside the `PostsController` that you just generated. This is because when controllers are generated in Rails -they are empty by default, unless you tell it you wanted actions during the +they are empty by default, unless you tell it your wanted actions during the generation process. To manually define an action inside a controller, all you need to do is to -- cgit v1.2.3 From 330883196bf54f93acfdb1587ac86480e755a928 Mon Sep 17 00:00:00 2001 From: Prashant Sahni Date: Fri, 13 Dec 2013 14:03:44 +0530 Subject: form_tag with parameters fixed [ ci skip ] --- guides/source/action_view_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md index 769be9840c..2f1bd313a1 100644 --- a/guides/source/action_view_overview.md +++ b/guides/source/action_view_overview.md @@ -1285,7 +1285,7 @@ Creates a field set for grouping HTML form elements. Creates a file upload field. ```html+erb -<%= form_tag {action: "post"}, {multipart: true} do %> +<%= form_tag({action:"post"}, multipart: true) do %> <%= file_field_tag "file" %> <%= submit_tag %> <% end %> -- cgit v1.2.3 From 02caba2b8617cd8c64927071f48905ca63325ab7 Mon Sep 17 00:00:00 2001 From: Juanito Fatas Date: Sat, 14 Dec 2013 19:22:04 +0800 Subject: Improve document: working with javascript in rails [ci skip]. * Add form_tag generated output. * improve some text. * data-remote='true' should use double quotes. --- guides/source/working_with_javascript_in_rails.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'guides/source') diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md index 301e0e7e6c..3c04204c29 100644 --- a/guides/source/working_with_javascript_in_rails.md +++ b/guides/source/working_with_javascript_in_rails.md @@ -169,7 +169,7 @@ This will generate the following HTML: ``` -Note the `data-remote='true'`. Now, the form will be submitted by Ajax rather +Note the `data-remote="true"`. Now, the form will be submitted by Ajax rather than by the browser's normal submit mechanism. You probably don't want to just sit there with a filled out `
    `, though. @@ -194,7 +194,17 @@ is very similar to `form_for`. It has a `:remote` option that you can use like this: ```erb -<%= form_tag('/posts', remote: true) %> +<%= form_tag('/posts', remote: true) do %> + ... +<% end %> +``` + +This will generate the following HTML: + +```html + + ... +
    ``` Everything else is the same as `form_for`. See its documentation for full @@ -299,10 +309,10 @@ The `app/views/users/_user.html.erb` partial contains the following: The top portion of the index page displays the users. The bottom portion provides a form to create a new user. -The bottom form will call the create action on the Users controller. Because +The bottom form will call the `create` action on the `UsersController`. Because the form's remote option is set to true, the request will be posted to the -users controller as an Ajax request, looking for JavaScript. In order to -service that request, the create action of your controller would look like +`UsersController` as an Ajax request, looking for JavaScript. In order to +serve that request, the `create` action of your controller would look like this: ```ruby -- cgit v1.2.3 From e10f91000be7e67e7fa6768088f381668d81be05 Mon Sep 17 00:00:00 2001 From: Kuldeep Aggarwal Date: Sat, 14 Dec 2013 22:49:00 +0530 Subject: Improved documents [ci skip] --- guides/source/3_2_release_notes.md | 2 +- guides/source/action_view_overview.md | 2 +- guides/source/form_helpers.md | 2 +- guides/source/layouts_and_rendering.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'guides/source') diff --git a/guides/source/3_2_release_notes.md b/guides/source/3_2_release_notes.md index a9484cf97a..ce811a583b 100644 --- a/guides/source/3_2_release_notes.md +++ b/guides/source/3_2_release_notes.md @@ -238,7 +238,7 @@ Action Pack end ``` - In the example above, Posts controller will no longer automatically look up for a posts layout. If you need this functionality you could either remove `layout "application"` from `ApplicationController` or explicitly set it to `nil` in `PostsController`. + In the example above, `PostsController` will no longer automatically look up for a posts layout. If you need this functionality you could either remove `layout "application"` from `ApplicationController` or explicitly set it to `nil` in `PostsController`. * Deprecated `ActionController::UnknownAction` in favor of `AbstractController::ActionNotFound`. diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md index 2f1bd313a1..6a355a5177 100644 --- a/guides/source/action_view_overview.md +++ b/guides/source/action_view_overview.md @@ -1591,7 +1591,7 @@ Localized Views Action View has the ability render different templates depending on the current locale. -For example, suppose you have a Posts controller with a show action. By default, calling this action will render `app/views/posts/show.html.erb`. But if you set `I18n.locale = :de`, then `app/views/posts/show.de.html.erb` will be rendered instead. If the localized template isn't present, the undecorated version will be used. This means you're not required to provide localized views for all cases, but they will be preferred and used if available. +For example, suppose you have a `PostsController` with a show action. By default, calling this action will render `app/views/posts/show.html.erb`. But if you set `I18n.locale = :de`, then `app/views/posts/show.de.html.erb` will be rendered instead. If the localized template isn't present, the undecorated version will be used. This means you're not required to provide localized views for all cases, but they will be preferred and used if available. You can use the same technique to localize the rescue files in your public directory. For example, setting `I18n.locale = :de` and creating `public/500.de.html` and `public/404.de.html` would allow you to have localized rescue pages. diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md index e8279b9c0c..ec4a255398 100644 --- a/guides/source/form_helpers.md +++ b/guides/source/form_helpers.md @@ -342,7 +342,7 @@ If you have created namespaced routes, `form_for` has a nifty shorthand for that form_for [:admin, @article] ``` -will create a form that submits to the articles controller inside the admin namespace (submitting to `admin_article_path(@article)` in the case of an update). If you have several levels of namespacing then the syntax is similar: +will create a form that submits to the `ArticlesController` inside the admin namespace (submitting to `admin_article_path(@article)` in the case of an update). If you have several levels of namespacing then the syntax is similar: ```ruby form_for [:admin, :management, @article] diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md index f4dab57aa5..c2d9772063 100644 --- a/guides/source/layouts_and_rendering.md +++ b/guides/source/layouts_and_rendering.md @@ -404,7 +404,7 @@ class ProductsController < ApplicationController end ``` -With this declaration, all of the views rendered by the products controller will use `app/views/layouts/inventory.html.erb` as their layout. +With this declaration, all of the views rendered by the `ProductsController` will use `app/views/layouts/inventory.html.erb` as their layout. To assign a specific layout for the entire application, use a `layout` declaration in your `ApplicationController` class: -- cgit v1.2.3 From 39eb10c3b5e1cc4b3537a8d815f44d762e032b88 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sat, 14 Dec 2013 13:27:45 -0700 Subject: Clarification, grammar fixes, punctuation, and capitalization [ci skip] --- guides/source/engines.md | 171 ++++++++++++++++++++++++----------------------- 1 file changed, 87 insertions(+), 84 deletions(-) (limited to 'guides/source') diff --git a/guides/source/engines.md b/guides/source/engines.md index 2266b1fd7f..c9be76e05d 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -20,7 +20,7 @@ Engines can be considered miniature applications that provide functionality to t Therefore, engines and applications can be thought of almost the same thing, just with subtle differences, as you'll see throughout this guide. Engines and applications also share a common structure. -Engines are also closely related to plugins where the two share a common `lib` directory structure and are both generated using the `rails plugin new` generator. The difference being that an engine is considered a "full plugin" by Rails as indicated by the `--full` option that's passed to the generator command, but this guide will refer to them simply as "engines" throughout. An engine **can** be a plugin, and a plugin **can** be an engine. +Engines are also closely related to plugins. The two share a common `lib` directory structure, and are both generated using the `rails plugin new` generator. The difference is that an engine is considered a "full plugin" by Rails (as indicated by the `--full` option that's passed to the generator command). This guide will refer to them simply as "engines" throughout. An engine **can** be a plugin, and a plugin **can** be an engine. The engine that will be created in this guide will be called "blorgh". The engine will provide blogging functionality to its host applications, allowing for new posts and comments to be created. At the beginning of this guide, you will be working solely within the engine itself, but in later sections you'll see how to hook it into an application. @@ -47,7 +47,7 @@ The full list of options for the plugin generator may be seen by typing: $ rails plugin --help ``` -The `--full` option tells the generator that you want to create an engine, including a skeleton structure by providing the following: +The `--full` option tells the generator that you want to create an engine, including a skeleton structure that provides the following: * An `app` directory tree * A `config/routes.rb` file: @@ -56,7 +56,7 @@ The `--full` option tells the generator that you want to create an engine, inclu Rails.application.routes.draw do end ``` - * A file at `lib/blorgh/engine.rb` which is identical in function to a standard Rails application's `config/application.rb` file: + * A file at `lib/blorgh/engine.rb`, which is identical in function to a standard Rails application's `config/application.rb` file: ```ruby module Blorgh @@ -94,9 +94,9 @@ Additionally, the `--mountable` option tells the generator to mount the engine i mount Blorgh::Engine, at: "blorgh" ``` -### Inside an engine +### Inside an Engine -#### Critical files +#### Critical Files At the root of this brand new engine's directory lives a `blorgh.gemspec` file. When you include the engine into an application later on, you will do so with this line in the Rails application's `Gemfile`: @@ -113,7 +113,7 @@ module Blorgh end ``` -TIP: Some engines choose to use this file to put global configuration options for their engine. It's a relatively good idea, and so if you want to offer configuration options, the file where your engine's `module` is defined is perfect for that. Place the methods inside the module and you'll be good to go. +TIP: Some engines choose to use this file to put global configuration options for their engine. It's a relatively good idea, so if you want to offer configuration options, the file where your engine's `module` is defined is perfect for that. Place the methods inside the module and you'll be good to go. Within `lib/blorgh/engine.rb` is the base class for the engine: @@ -127,7 +127,7 @@ end By inheriting from the `Rails::Engine` class, this gem notifies Rails that there's an engine at the specified path, and will correctly mount the engine inside the application, performing tasks such as adding the `app` directory of the engine to the load path for models, mailers, controllers and views. -The `isolate_namespace` method here deserves special notice. This call is responsible for isolating the controllers, models, routes and other things into their own namespace, away from similar components inside the application. Without this, there is a possibility that the engine's components could "leak" into the application, causing unwanted disruption, or that important engine components could be overridden by similarly named things within the application. One of the examples of such conflicts are helpers. Without calling `isolate_namespace`, engine's helpers would be included in an application's controllers. +The `isolate_namespace` method here deserves special notice. This call is responsible for isolating the controllers, models, routes and other things into their own namespace, away from similar components inside the application. Without this, there is a possibility that the engine's components could "leak" into the application, causing unwanted disruption, or that important engine components could be overridden by similarly named things within the application. One of the examples of such conflicts is helpers. Without calling `isolate_namespace`, the engine's helpers would be included in an application's controllers. NOTE: It is **highly** recommended that the `isolate_namespace` line be left within the `Engine` class definition. Without it, classes generated in an engine **may** conflict with an application. @@ -135,31 +135,31 @@ What this isolation of the namespace means is that a model generated by a call t Finally, routes will also be isolated within the engine. This is one of the most important parts about namespacing, and is discussed later in the [Routes](#routes) section of this guide. -#### `app` directory +#### `app` Directory -Inside the `app` directory are the standard `assets`, `controllers`, `helpers`, `mailers`, `models` and `views` directories that you should be familiar with from an application. The `helpers`, `mailers` and `models` directories are empty and so aren't described in this section. We'll look more into models in a future section, when we're writing the engine. +Inside the `app` directory are the standard `assets`, `controllers`, `helpers`, `mailers`, `models` and `views` directories that you should be familiar with from an application. The `helpers`, `mailers` and `models` directories are empty, so they aren't described in this section. We'll look more into models in a future section, when we're writing the engine. -Within the `app/assets` directory, there are the `images`, `javascripts` and `stylesheets` directories which, again, you should be familiar with due to their similarity to an application. One difference here however is that each directory contains a sub-directory with the engine name. Because this engine is going to be namespaced, its assets should be too. +Within the `app/assets` directory, there are the `images`, `javascripts` and `stylesheets` directories which, again, you should be familiar with due to their similarity to an application. One difference here, however, is that each directory contains a sub-directory with the engine name. Because this engine is going to be namespaced, its assets should be too. -Within the `app/controllers` directory there is a `blorgh` directory and inside that a file called `application_controller.rb`. This file will provide any common functionality for the controllers of the engine. The `blorgh` directory is where the other controllers for the engine will go. By placing them within this namespaced directory, you prevent them from possibly clashing with identically-named controllers within other engines or even within the application. +Within the `app/controllers` directory there is a `blorgh` directory that contains a file called `application_controller.rb`. This file will provide any common functionality for the controllers of the engine. The `blorgh` directory is where the other controllers for the engine will go. By placing them within this namespaced directory, you prevent them from possibly clashing with identically-named controllers within other engines or even within the application. NOTE: The `ApplicationController` class inside an engine is named just like a Rails application in order to make it easier for you to convert your applications into engines. -Lastly, the `app/views` directory contains a `layouts` folder which contains a file at `blorgh/application.html.erb` which allows you to specify a layout for the engine. If this engine is to be used as a stand-alone engine, then you would add any customization to its layout in this file, rather than the application's `app/views/layouts/application.html.erb` file. +Lastly, the `app/views` directory contains a `layouts` folder, which contains a file at `blorgh/application.html.erb`. This file allows you to specify a layout for the engine. If this engine is to be used as a stand-alone engine, then you would add any customization to its layout in this file, rather than the application's `app/views/layouts/application.html.erb` file. If you don't want to force a layout on to users of the engine, then you can delete this file and reference a different layout in the controllers of your engine. -#### `bin` directory +#### `bin` Directory -This directory contains one file, `bin/rails`, which enables you to use the `rails` sub-commands and generators just like you would within an application. This means that you will very easily be able to generate new controllers and models for this engine by running commands like this: +This directory contains one file, `bin/rails`, which enables you to use the `rails` sub-commands and generators just like you would within an application. This means that you will be able to generate new controllers and models for this engine very easily by running commands like this: ```bash rails g model ``` -Keeping in mind, of course, that anything generated with these commands inside an engine that has `isolate_namespace` inside the `Engine` class will be namespaced. +Keep in mind, of course, that anything generated with these commands inside of an engine that has `isolate_namespace` in the `Engine` class will be namespaced. -#### `test` directory +#### `test` Directory The `test` directory is where tests for the engine will go. To test the engine, there is a cut-down version of a Rails application embedded within it at `test/dummy`. This application will mount the engine in the `test/dummy/config/routes.rb` file: @@ -171,14 +171,14 @@ end This line mounts the engine at the path `/blorgh`, which will make it accessible through the application only at that path. -In the test directory there is the `test/integration` directory, where integration tests for the engine should be placed. Other directories can be created in the `test` directory as well. For example, you may wish to create a `test/models` directory for your models tests. +Inside the test directory there is the `test/integration` directory, where integration tests for the engine should be placed. Other directories can be created in the `test` directory as well. For example, you may wish to create a `test/models` directory for your model tests. Providing engine functionality ------------------------------ The engine that this guide covers provides posting and commenting functionality and follows a similar thread to the [Getting Started Guide](getting_started.html), with some new twists. -### Generating a post resource +### Generating a Post Resource The first thing to generate for a blog engine is the `Post` model and related controller. To quickly generate this, you can use the Rails scaffold generator. @@ -195,7 +195,8 @@ create app/models/blorgh/post.rb invoke test_unit create test/models/blorgh/post_test.rb create test/fixtures/blorgh/posts.yml - route resources :posts +invoke resource_route + route resources :posts invoke scaffold_controller create app/controllers/blorgh/posts_controller.rb invoke erb @@ -233,7 +234,7 @@ end ``` Note here that the routes are drawn upon the `Blorgh::Engine` object rather than the `YourApp::Application` class. This is so that the engine routes are confined to the engine itself and can be mounted at a specific point as shown in the [test directory](#test-directory) section. It also causes the engine's routes to be isolated from those routes that are within the application. The [Routes](#routes) section of -this guide describes it in details. +this guide describes it in detail. Next, the `scaffold_controller` generator is invoked, generating a controller called `Blorgh::PostsController` (at `app/controllers/blorgh/posts_controller.rb`) and its related views at `app/views/blorgh/posts`. This generator also generates a test for the controller (`test/controllers/blorgh/posts_controller_test.rb`) and a helper (`app/helpers/blorgh/posts_controller.rb`). @@ -261,9 +262,9 @@ end This helps prevent conflicts with any other engine or application that may have a post resource as well. -Finally, two files that are the assets for this resource are generated, `app/assets/javascripts/blorgh/posts.js` and `app/assets/stylesheets/blorgh/posts.css`. You'll see how to use these a little later. +Finally, the assets for this resource are generated in two files: `app/assets/javascripts/blorgh/posts.js` and `app/assets/stylesheets/blorgh/posts.css`. You'll see how to use these a little later. -By default, the scaffold styling is not applied to the engine as the engine's layout file, `app/views/layouts/blorgh/application.html.erb` doesn't load it. To make this apply, insert this line into the `` tag of this layout: +By default, the scaffold styling is not applied to the engine because the engine's layout file, `app/views/layouts/blorgh/application.html.erb`, doesn't load it. To make the scaffold styling apply, insert this line into the `` tag of this layout: ```erb <%= stylesheet_link_tag "scaffold" %> @@ -286,11 +287,11 @@ root to: "posts#index" Now people will only need to go to the root of the engine to see all the posts, rather than visiting `/posts`. This means that instead of `http://localhost:3000/blorgh/posts`, you only need to go to `http://localhost:3000/blorgh` now. -### Generating a comments resource +### Generating a Comments Resource Now that the engine can create new blog posts, it only makes sense to add commenting functionality as well. To do this, you'll need to generate a comment model, a comment controller and then modify the posts scaffold to display comments and allow people to create new ones. -Run the model generator and tell it to generate a `Comment` model, with the related table having two columns: a `post_id` integer and `text` text column. +From the application root, run the model generator. Tell it to generate a `Comment` model, with the related table having two columns: a `post_id` integer and `text` text column. ```bash $ rails generate model Comment post_id:integer text:text @@ -367,7 +368,7 @@ end This creates a nested route for the comments, which is what the form requires. -The route now exists, but the controller that this route goes to does not. To create it, run this command: +The route now exists, but the controller that this route goes to does not. To create it, run this command from the application root: ```bash $ rails g controller comments @@ -392,7 +393,7 @@ invoke css create app/assets/stylesheets/blorgh/comments.css ``` -The form will be making a `POST` request to `/posts/:post_id/comments`, which will correspond with the `create` action in `Blorgh::CommentsController`. This action needs to be created and can be done by putting the following lines inside the class definition in `app/controllers/blorgh/comments_controller.rb`: +The form will be making a `POST` request to `/posts/:post_id/comments`, which will correspond with the `create` action in `Blorgh::CommentsController`. This action needs to be created, which can be done by putting the following lines inside the class definition in `app/controllers/blorgh/comments_controller.rb`: ```ruby def create @@ -408,7 +409,7 @@ private end ``` -This is the final part required to get the new comment form working. Displaying the comments however, is not quite right yet. If you were to create a comment right now you would see this error: +This is the final step required to get the new comment form working. Displaying the comments, however, is not quite right yet. If you were to create a comment right now, you would see this error: ``` Missing partial blorgh/comments/comment with {:handlers=>[:erb, :builder], :formats=>[:html], :locale=>[:en, :en]}. Searched in: @@ -424,16 +425,16 @@ This partial will be responsible for rendering just the comment text, for now. C <%= comment_counter + 1 %>. <%= comment.text %> ``` -The `comment_counter` local variable is given to us by the `<%= render @post.comments %>` call, as it will define this automatically and increment the counter as it iterates through each comment. It's used in this example to display a small number next to each comment when it's created. +The `comment_counter` local variable is given to us by the `<%= render @post.comments %>` call, which will define it automatically and increment the counter as it iterates through each comment. It's used in this example to display a small number next to each comment when it's created. That completes the comment function of the blogging engine. Now it's time to use it within an application. -Hooking into an application +Hooking Into an Application --------------------------- Using an engine within an application is very easy. This section covers how to mount the engine into an application and the initial setup required, as well as linking the engine to a `User` class provided by the application to provide ownership for posts and comments within the engine. -### Mounting the engine +### Mounting the Engine First, the engine needs to be specified inside the application's `Gemfile`. If there isn't an application handy to test this out in, generate one using the `rails new` command outside of the engine directory like this: @@ -453,7 +454,9 @@ However, because you are developing the `blorgh` engine on your local machine, y gem 'blorgh', path: "/path/to/blorgh" ``` -As described earlier, by placing the gem in the `Gemfile` it will be loaded when Rails is loaded, as it will first require `lib/blorgh.rb` in the engine and then `lib/blorgh/engine.rb`, which is the file that defines the major pieces of functionality for the engine. +Then run `bundle` to install the gem. + +As described earlier, by placing the gem in the `Gemfile` it will be loaded when Rails is loaded. It will first require `lib/blorgh.rb` from the engine, then `lib/blorgh/engine.rb`, which is the file that defines the major pieces of functionality for the engine. To make the engine's functionality accessible from within an application, it needs to be mounted in that application's `config/routes.rb` file: @@ -463,7 +466,7 @@ mount Blorgh::Engine, at: "/blog" This line will mount the engine at `/blog` in the application. Making it accessible at `http://localhost:3000/blog` when the application runs with `rails server`. -NOTE: Other engines, such as Devise, handle this a little differently by making you specify custom helpers such as `devise_for` in the routes. These helpers do exactly the same thing, mounting pieces of the engines's functionality at a pre-defined path which may be customizable. +NOTE: Other engines, such as Devise, handle this a little differently by making you specify custom helpers (such as `devise_for`) in the routes. These helpers do exactly the same thing, mounting pieces of the engines's functionality at a pre-defined path which may be customizable. ### Engine setup @@ -486,7 +489,7 @@ Copied migration [timestamp_1]_create_blorgh_posts.rb from blorgh Copied migration [timestamp_2]_create_blorgh_comments.rb from blorgh ``` -The first timestamp (`[timestamp_1]`) will be the current time and the second timestamp (`[timestamp_2]`) will be the current time plus a second. The reason for this is so that the migrations for the engine are run after any existing migrations in the application. +The first timestamp (`[timestamp_1]`) will be the current time, and the second timestamp (`[timestamp_2]`) will be the current time plus a second. The reason for this is so that the migrations for the engine are run after any existing migrations in the application. To run these migrations within the context of the application, simply run `rake db:migrate`. When accessing the engine through `http://localhost:3000/blog`, the posts will be empty. This is because the table created inside the application is different from the one created within the engine. Go ahead, play around with the newly mounted engine. You'll find that it's the same as when it was only an engine. @@ -496,21 +499,21 @@ If you would like to run migrations only from one engine, you can do it by speci rake db:migrate SCOPE=blorgh ``` -This may be useful if you want to revert engine's migrations before removing it. In order to revert all migrations from blorgh engine you can run such code: +This may be useful if you want to revert engine's migrations before removing it. To revert all migrations from blorgh engine you can run code such as: ```bash rake db:migrate SCOPE=blorgh VERSION=0 ``` -### Using a class provided by the application +### Using a Class Provided by the Application -#### Using a model provided by the application +#### Using a Model Provided by the Application When an engine is created, it may want to use specific classes from an application to provide links between the pieces of the engine and the pieces of the application. In the case of the `blorgh` engine, making posts and comments have authors would make a lot of sense. A typical application might have a `User` class that would be used to represent authors for a post or a comment. But there could be a case where the application calls this class something different, such as `Person`. For this reason, the engine should not hardcode associations specifically for a `User` class. -To keep it simple in this case, the application will have a class called `User` which will represent the users of the application. It can be generated using this command inside the application: +To keep it simple in this case, the application will have a class called `User` that represents the users of the application. It can be generated using this command inside the application: ```bash rails g model user name:string @@ -518,7 +521,7 @@ rails g model user name:string The `rake db:migrate` command needs to be run here to ensure that our application has the `users` table for future use. -Also, to keep it simple, the posts form will have a new text field called `author_name` where users can elect to put their name. The engine will then take this name and create a new `User` object from it or find one that already has that name, and then associate the post with it. +Also, to keep it simple, the posts form will have a new text field called `author_name`, where users can elect to put their name. The engine will then take this name and either create a new `User` object from it, or find one that already has that name. The engine will then associate the post with the found or created `User` object. First, the `author_name` text field needs to be added to the `app/views/blorgh/posts/_form.html.erb` partial inside the engine. This can be added above the `title` field with this code: @@ -537,7 +540,7 @@ def post_params end ``` -The `Blorgh::Post` model should then have some code to convert the `author_name` field into an actual `User` object and associate it as that post's `author` before the post is saved. It will also need to have an `attr_accessor` setup for this field so that the setter and getter methods are defined for it. +The `Blorgh::Post` model should then have some code to convert the `author_name` field into an actual `User` object and associate it as that post's `author` before the post is saved. It will also need to have an `attr_accessor` set up for this field, so that the setter and getter methods are defined for it. To do all this, you'll need to add the `attr_accessor` for `author_name`, the association for the author and the `before_save` call into `app/models/blorgh/post.rb`. The `author` association will be hard-coded to the `User` class for the time being. @@ -553,7 +556,7 @@ private end ``` -By defining that the `author` association's object is represented by the `User` class a link is established between the engine and the application. There needs to be a way of associating the records in the `blorgh_posts` table with the records in the `users` table. Because the association is called `author`, there should be an `author_id` column added to the `blorgh_posts` table. +By representing the `author` association's object with the `User` class, a link is established between the engine and the application. There needs to be a way of associating the records in the `blorgh_posts` table with the records in the `users` table. Because the association is called `author`, there should be an `author_id` column added to the `blorgh_posts` table. To generate this new column, run this command within the engine: @@ -569,7 +572,7 @@ This migration will need to be run on the application. To do that, it must first $ rake blorgh:install:migrations ``` -Notice here that only _one_ migration was copied over here. This is because the first two migrations were copied over the first time this command was run. +Notice that only _one_ migration was copied over here. This is because the first two migrations were copied over the first time this command was run. ``` NOTE Migration [timestamp]_create_blorgh_posts.rb from blorgh has been skipped. Migration with the same name already exists. @@ -577,7 +580,7 @@ NOTE Migration [timestamp]_create_blorgh_comments.rb from blorgh has been skippe Copied migration [timestamp]_add_author_id_to_blorgh_posts.rb from blorgh ``` -Run this migration using this command: +Run the migration using: ```bash $ rake db:migrate @@ -600,7 +603,7 @@ By outputting `@post.author` using the `<%=` tag, the `to_s` method will be call # ``` -This is undesirable and it would be much better to have the user's name there. To do this, add a `to_s` method to the `User` class within the application: +This is undesirable. It would be much better to have the user's name there. To do this, add a `to_s` method to the `User` class within the application: ```ruby def to_s @@ -608,44 +611,44 @@ def to_s end ``` -Now instead of the ugly Ruby object output the author's name will be displayed. +Now instead of the ugly Ruby object output, the author's name will be displayed. -#### Using a controller provided by the application +#### Using a Controller Provided by the Application -Because Rails controllers generally share code for things like authentication and accessing session variables, by default they inherit from `ApplicationController`. Rails engines, however are scoped to run independently from the main application, so each engine gets a scoped `ApplicationController`. This namespace prevents code collisions, but often engine controllers should access methods in the main application's `ApplicationController`. An easy way to provide this access is to change the engine's scoped `ApplicationController` to inherit from the main application's `ApplicationController`. For our Blorgh engine this would be done by changing `app/controllers/blorgh/application_controller.rb` to look like: +Because Rails controllers generally share code for things like authentication and accessing session variables, they inherit from `ApplicationController` by default. Rails engines, however are scoped to run independently from the main application, so each engine gets a scoped `ApplicationController`. This namespace prevents code collisions, but often engine controllers need to access methods in the main application's `ApplicationController`. An easy way to provide this access is to change the engine's scoped `ApplicationController` to inherit from the main application's `ApplicationController`. For our Blorgh engine this would be done by changing `app/controllers/blorgh/application_controller.rb` to look like: ```ruby class Blorgh::ApplicationController < ApplicationController end ``` -By default, the engine's controllers inherit from `Blorgh::ApplicationController`. So, after making this change they will have access to the main applications `ApplicationController` as though they were part of the main application. +By default, the engine's controllers inherit from `Blorgh::ApplicationController`. So, after making this change they will have access to the main application's `ApplicationController`, as though they were part of the main application. This change does require that the engine is run from a Rails application that has an `ApplicationController`. -### Configuring an engine +### Configuring an Engine This section covers how to make the `User` class configurable, followed by general configuration tips for the engine. -#### Setting configuration settings in the application +#### Setting Configuration Settings in the Application -The next step is to make the class that represents a `User` in the application customizable for the engine. This is because, as explained before, that class may not always be `User`. To make this customizable, the engine will have a configuration setting called `author_class` that will be used to specify what the class representing users is inside the application. +The next step is to make the class that represents a `User` in the application customizable for the engine. This is because that class may not always be `User`, as previously explained. To make this setting customizable, the engine will have a configuration setting called `author_class` that will be used to specify which class represents users inside the application. -To define this configuration setting, you should use a `mattr_accessor` inside the `Blorgh` module for the engine, located at `lib/blorgh.rb` inside the engine. Inside this module, put this line: +To define this configuration setting, you should use a `mattr_accessor` inside the `Blorgh` module for the engine. Add this line to `lib/blorgh.rb` inside the engine: ```ruby mattr_accessor :author_class ``` -This method works like its brothers `attr_accessor` and `cattr_accessor`, but provides a setter and getter method on the module with the specified name. To use it, it must be referenced using `Blorgh.author_class`. +This method works like its brothers, `attr_accessor` and `cattr_accessor`, but provides a setter and getter method on the module with the specified name. To use it, it must be referenced using `Blorgh.author_class`. -The next step is switching the `Blorgh::Post` model over to this new setting. For the `belongs_to` association inside this model (`app/models/blorgh/post.rb`), it will now become this: +The next step is to switch the `Blorgh::Post` model over to this new setting. Change the `belongs_to` association inside this model (`app/models/blorgh/post.rb`) to this: ```ruby belongs_to :author, class_name: Blorgh.author_class ``` -The `set_author` method also located in this class should also use this class: +The `set_author` method in the `Blorgh::Post` model should also use this class: ```ruby self.author = Blorgh.author_class.constantize.find_or_create_by(name: author_name) @@ -675,7 +678,7 @@ in the `Blorgh::Post` model: belongs_to :author, class_name: Blorgh.author_class.to_s ``` -To set this configuration setting within the application, an initializer should be used. By using an initializer, the configuration will be set up before the application starts and calls the engine's models which may depend on this configuration setting existing. +To set this configuration setting within the application, an initializer should be used. By using an initializer, the configuration will be set up before the application starts and calls the engine's models, which may depend on this configuration setting existing. Create a new initializer at `config/initializers/blorgh.rb` inside the application where the `blorgh` engine is installed and put this content in it: @@ -683,15 +686,15 @@ Create a new initializer at `config/initializers/blorgh.rb` inside the applicati Blorgh.author_class = "User" ``` -WARNING: It's very important here to use the `String` version of the class, rather than the class itself. If you were to use the class, Rails would attempt to load that class and then reference the related table, which could lead to problems if the table wasn't already existing. Therefore, a `String` should be used and then converted to a class using `constantize` in the engine later on. +WARNING: It's very important here to use the `String` version of the class, rather than the class itself. If you were to use the class, Rails would attempt to load that class and then reference the related table. This could lead to problems if the table wasn't already existing. Therefore, a `String` should be used and then converted to a class using `constantize` in the engine later on. Go ahead and try to create a new post. You will see that it works exactly in the same way as before, except this time the engine is using the configuration setting in `config/initializers/blorgh.rb` to learn what the class is. -There are now no strict dependencies on what the class is, only what the API for the class must be. The engine simply requires this class to define a `find_or_create_by` method which returns an object of that class to be associated with a post when it's created. This object, of course, should have some sort of identifier by which it can be referenced. +There are now no strict dependencies on what the class is, only what the API for the class must be. The engine simply requires this class to define a `find_or_create_by` method which returns an object of that class, to be associated with a post when it's created. This object, of course, should have some sort of identifier by which it can be referenced. -#### General engine configuration +#### General Engine Configuration -Within an engine, there may come a time where you wish to use things such as initializers, internationalization or other configuration options. The great news is that these things are entirely possible because a Rails engine shares much the same functionality as a Rails application. In fact, a Rails application's functionality is actually a superset of what is provided by engines! +Within an engine, there may come a time where you wish to use things such as initializers, internationalization or other configuration options. The great news is that these things are entirely possible, because a Rails engine shares much the same functionality as a Rails application. In fact, a Rails application's functionality is actually a superset of what is provided by engines! If you wish to use an initializer - code that should run before the engine is loaded - the place for it is the `config/initializers` folder. This directory's @@ -705,11 +708,11 @@ For locales, simply place the locale files in the `config/locales` directory, ju Testing an engine ----------------- -When an engine is generated there is a smaller dummy application created inside it at `test/dummy`. This application is used as a mounting point for the engine to make testing the engine extremely simple. You may extend this application by generating controllers, models or views from within the directory, and then use those to test your engine. +When an engine is generated, there is a smaller dummy application created inside it at `test/dummy`. This application is used as a mounting point for the engine, to make testing the engine extremely simple. You may extend this application by generating controllers, models or views from within the directory, and then use those to test your engine. The `test` directory should be treated like a typical Rails testing environment, allowing for unit, functional and integration tests. -### Functional tests +### Functional Tests A matter worth taking into consideration when writing functional tests is that the tests are going to be running on an application - the `test/dummy` application - rather than your engine. This is due to the setup of the testing environment; an engine needs an application as a host for testing its main functionality, especially controllers. This means that if you were to make a typical `GET` to a controller in a controller's functional test like this: @@ -717,13 +720,13 @@ A matter worth taking into consideration when writing functional tests is that t get :index ``` -It may not function correctly. This is because the application doesn't know how to route these requests to the engine unless you explicitly tell it **how**. To do this, you must pass the `:use_route` option (as a parameter) on these requests also: +It may not function correctly. This is because the application doesn't know how to route these requests to the engine unless you explicitly tell it **how**. To do this, you must also pass the `:use_route` option as a parameter on these requests: ```ruby get :index, use_route: :blorgh ``` -This tells the application that you still want to perform a `GET` request to the `index` action of this controller, just that you want to use the engine's route to get there, rather than the application. +This tells the application that you still want to perform a `GET` request to the `index` action of this controller, but you want to use the engine's route to get there, rather than the application's one. Improving engine functionality ------------------------------ @@ -734,9 +737,9 @@ This section explains how to add and/or override engine MVC functionality in the Engine model and controller classes can be extended by open classing them in the main Rails application (since model and controller classes are just Ruby classes that inherit Rails specific functionality). Open classing an Engine class redefines it for use in the main application. This is usually implemented by using the decorator pattern. -For simple class modifications use `Class#class_eval`, and for complex class modifications, consider using `ActiveSupport::Concern`. +For simple class modifications, use `Class#class_eval`. For complex class modifications, consider using `ActiveSupport::Concern`. -#### A note on Decorators and loading code +#### A note on Decorators and Loading Code Because these decorators are not referenced by your Rails application itself, Rails' autoloading system will not kick in and load your decorators. This @@ -764,7 +767,7 @@ that isn't referenced by your main application. #### Implementing Decorator Pattern Using Class#class_eval -**Adding** `Post#time_since_created`, +**Adding** `Post#time_since_created`: ```ruby # MyApp/app/decorators/models/blorgh/post_decorator.rb @@ -785,7 +788,7 @@ end ``` -**Overriding** `Post#summary` +**Overriding** `Post#summary`: ```ruby # MyApp/app/decorators/models/blorgh/post_decorator.rb @@ -812,7 +815,7 @@ end Using `Class#class_eval` is great for simple adjustments, but for more complex class modifications, you might want to consider using [`ActiveSupport::Concern`](http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html). ActiveSupport::Concern manages load order of interlinked dependent modules and classes at run time allowing you to significantly modularize your code. -**Adding** `Post#time_since_created` and **Overriding** `Post#summary` +**Adding** `Post#time_since_created` and **Overriding** `Post#summary`: ```ruby # MyApp/app/models/blorgh/post.rb @@ -845,7 +848,7 @@ module Blorgh::Concerns::Models::Post extend ActiveSupport::Concern # 'included do' causes the included code to be evaluated in the - # context where it is included (post.rb), rather than be + # context where it is included (post.rb), rather than being # executed in the module's context (blorgh/concerns/models/post). included do attr_accessor :author_name @@ -871,11 +874,11 @@ module Blorgh::Concerns::Models::Post end ``` -### Overriding views +### Overriding Views -When Rails looks for a view to render, it will first look in the `app/views` directory of the application. If it cannot find the view there, then it will check in the `app/views` directories of all engines which have this directory. +When Rails looks for a view to render, it will first look in the `app/views` directory of the application. If it cannot find the view there, it will check in the `app/views` directories of all engines that have this directory. -When the application is asked to render the view for `Blorgh::PostsController`'s index action, it will look the path `app/views/blorgh/posts/index.html.erb`, first within the application. If it cannot find it, it will look inside the engine. +When the application is asked to render the view for `Blorgh::PostsController`'s index action, it will first look for the path `app/views/blorgh/posts/index.html.erb` within the application. If it cannot find it, it will look inside the engine. You can override this view in the application by simply creating a new file at `app/views/blorgh/posts/index.html.erb`. Then you can completely change what this view would normally output. @@ -894,7 +897,7 @@ Try this now by creating a new file at `app/views/blorgh/posts/index.html.erb` a ### Routes -Routes inside an engine are, by default, isolated from the application. This is done by the `isolate_namespace` call inside the `Engine` class. This essentially means that the application and its engines can have identically named routes and they will not clash. +Routes inside an engine are isolated from the application by default. This is done by the `isolate_namespace` call inside the `Engine` class. This essentially means that the application and its engines can have identically named routes and they will not clash. Routes inside an engine are drawn on the `Engine` class within `config/routes.rb`, like this: @@ -904,7 +907,7 @@ Blorgh::Engine.routes.draw do end ``` -By having isolated routes such as this, if you wish to link to an area of an engine from within an application, you will need to use the engine's routing proxy method. Calls to normal routing methods such as `posts_path` may end up going to undesired locations if both the application and the engine both have such a helper defined. +By having isolated routes such as this, if you wish to link to an area of an engine from within an application, you will need to use the engine's routing proxy method. Calls to normal routing methods such as `posts_path` may end up going to undesired locations if both the application and the engine have such a helper defined. For instance, the following example would go to the application's `posts_path` if that template was rendered from the application, or the engine's `posts_path` if it was rendered from the engine: @@ -926,13 +929,13 @@ If you wish to reference the application inside the engine in a similar way, use If you were to use this inside an engine, it would **always** go to the application's root. If you were to leave off the `main_app` "routing proxy" method call, it could potentially go to the engine's or application's root, depending on where it was called from. -If a template is rendered from within an engine and it's attempting to use one of the application's routing helper methods, it may result in an undefined method call. If you encounter such an issue, ensure that you're not attempting to call the application's routing methods without the `main_app` prefix from within the engine. +If a template rendered from within an engine attempts to use one of the application's routing helper methods, it may result in an undefined method call. If you encounter such an issue, ensure that you're not attempting to call the application's routing methods without the `main_app` prefix from within the engine. ### Assets -Assets within an engine work in an identical way to a full application. Because the engine class inherits from `Rails::Engine`, the application will know to look up in the engine's `app/assets` and `lib/assets` directories for potential assets. +Assets within an engine work in an identical way to a full application. Because the engine class inherits from `Rails::Engine`, the application will know to look up assets in the engine's 'app/assets' and 'lib/assets' directories. -Much like all the other components of an engine, the assets should also be namespaced. This means if you have an asset called `style.css`, it should be placed at `app/assets/stylesheets/[engine name]/style.css`, rather than `app/assets/stylesheets/style.css`. If this asset wasn't namespaced, then there is a possibility that the host application could have an asset named identically, in which case the application's asset would take precedence and the engine's one would be all but ignored. +Like all of the other components of an engine, the assets should be namespaced. This means that if you have an asset called `style.css`, it should be placed at `app/assets/stylesheets/[engine name]/style.css`, rather than `app/assets/stylesheets/style.css`. If this asset isn't namespaced, there is a possibility that the host application could have an asset named identically, in which case the application's asset would take precedence and the engine's one would be ignored. Imagine that you did have an asset located at `app/assets/stylesheets/blorgh/style.css` To include this asset inside an application, just use `stylesheet_link_tag` and reference the asset as if it were inside the engine: @@ -940,7 +943,7 @@ Imagine that you did have an asset located at `app/assets/stylesheets/blorgh/sty <%= stylesheet_link_tag "blorgh/style.css" %> ``` -You can also specify these assets as dependencies of other assets using the Asset Pipeline require statements in processed files: +You can also specify these assets as dependencies of other assets using Asset Pipeline require statements in processed files: ``` /* @@ -954,10 +957,10 @@ INFO. Remember that in order to use languages like Sass or CoffeeScript, you sho There are some situations where your engine's assets are not required by the host application. For example, say that you've created an admin functionality that only exists for your engine. In this case, the host application doesn't need to require `admin.css` -or `admin.js`. Only the gem's admin layout needs these assets. It doesn't make sense for the host app to include `"blorgh/admin.css"` in it's stylesheets. In this situation, you should explicitly define these assets for precompilation. -This tells sprockets to add your engine assets when `rake assets:precompile` is ran. +or `admin.js`. Only the gem's admin layout needs these assets. It doesn't make sense for the host app to include `"blorgh/admin.css"` in its stylesheets. In this situation, you should explicitly define these assets for precompilation. +This tells sprockets to add your engine assets when `rake assets:precompile` is triggered. -You can define assets for precompilation in `engine.rb` +You can define assets for precompilation in `engine.rb`: ```ruby initializer "blorgh.assets.precompile" do |app| @@ -965,9 +968,9 @@ initializer "blorgh.assets.precompile" do |app| end ``` -For more information, read the [Asset Pipeline guide](asset_pipeline.html) +For more information, read the [Asset Pipeline guide](asset_pipeline.html). -### Other gem dependencies +### Other Gem Dependencies Gem dependencies inside an engine should be specified inside the `.gemspec` file at the root of the engine. The reason is that the engine may @@ -983,7 +986,7 @@ inside the `.gemspec` file in the engine: s.add_dependency "moo" ``` -To specify a dependency that should only be installed as a development +To specify a dependency that should only be installed as a development dependency of the application, specify it like this: ```ruby -- cgit v1.2.3 From f95d78e40267cf8eccb55cad26f0981a8ddc6374 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sat, 14 Dec 2013 13:28:08 -0700 Subject: Word wrapping engines guide [ci skip] --- guides/source/engines.md | 757 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 568 insertions(+), 189 deletions(-) (limited to 'guides/source') diff --git a/guides/source/engines.md b/guides/source/engines.md index c9be76e05d..87b0a1ac16 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -1,7 +1,9 @@ Getting Started with Engines ============================ -In this guide you will learn about engines and how they can be used to provide additional functionality to their host applications through a clean and very easy-to-use interface. +In this guide you will learn about engines and how they can be used to provide +additional functionality to their host applications through a clean and very +easy-to-use interface. After reading this guide, you will know: @@ -16,26 +18,59 @@ After reading this guide, you will know: What are engines? ----------------- -Engines can be considered miniature applications that provide functionality to their host applications. A Rails application is actually just a "supercharged" engine, with the `Rails::Application` class inheriting a lot of its behavior from `Rails::Engine`. - -Therefore, engines and applications can be thought of almost the same thing, just with subtle differences, as you'll see throughout this guide. Engines and applications also share a common structure. - -Engines are also closely related to plugins. The two share a common `lib` directory structure, and are both generated using the `rails plugin new` generator. The difference is that an engine is considered a "full plugin" by Rails (as indicated by the `--full` option that's passed to the generator command). This guide will refer to them simply as "engines" throughout. An engine **can** be a plugin, and a plugin **can** be an engine. - -The engine that will be created in this guide will be called "blorgh". The engine will provide blogging functionality to its host applications, allowing for new posts and comments to be created. At the beginning of this guide, you will be working solely within the engine itself, but in later sections you'll see how to hook it into an application. - -Engines can also be isolated from their host applications. This means that an application is able to have a path provided by a routing helper such as `posts_path` and use an engine also that provides a path also called `posts_path`, and the two would not clash. Along with this, controllers, models and table names are also namespaced. You'll see how to do this later in this guide. - -It's important to keep in mind at all times that the application should **always** take precedence over its engines. An application is the object that has final say in what goes on in the universe (with the universe being the application's environment) where the engine should only be enhancing it, rather than changing it drastically. - -To see demonstrations of other engines, check out [Devise](https://github.com/plataformatec/devise), an engine that provides authentication for its parent applications, or [Forem](https://github.com/radar/forem), an engine that provides forum functionality. There's also [Spree](https://github.com/spree/spree) which provides an e-commerce platform, and [RefineryCMS](https://github.com/refinery/refinerycms), a CMS engine. - -Finally, engines would not have been possible without the work of James Adam, Piotr Sarnacki, the Rails Core Team, and a number of other people. If you ever meet them, don't forget to say thanks! +Engines can be considered miniature applications that provide functionality to +their host applications. A Rails application is actually just a "supercharged" +engine, with the `Rails::Application` class inheriting a lot of its behavior +from `Rails::Engine`. + +Therefore, engines and applications can be thought of almost the same thing, +just with subtle differences, as you'll see throughout this guide. Engines and +applications also share a common structure. + +Engines are also closely related to plugins. The two share a common `lib` +directory structure, and are both generated using the `rails plugin new` +generator. The difference is that an engine is considered a "full plugin" by +Rails (as indicated by the `--full` option that's passed to the generator +command). This guide will refer to them simply as "engines" throughout. An +engine **can** be a plugin, and a plugin **can** be an engine. + +The engine that will be created in this guide will be called "blorgh". The +engine will provide blogging functionality to its host applications, allowing +for new posts and comments to be created. At the beginning of this guide, you +will be working solely within the engine itself, but in later sections you'll +see how to hook it into an application. + +Engines can also be isolated from their host applications. This means that an +application is able to have a path provided by a routing helper such as +`posts_path` and use an engine also that provides a path also called +`posts_path`, and the two would not clash. Along with this, controllers, models +and table names are also namespaced. You'll see how to do this later in this +guide. + +It's important to keep in mind at all times that the application should +**always** take precedence over its engines. An application is the object that +has final say in what goes on in the universe (with the universe being the +application's environment) where the engine should only be enhancing it, rather +than changing it drastically. + +To see demonstrations of other engines, check out +[Devise](https://github.com/plataformatec/devise), an engine that provides +authentication for its parent applications, or +[Forem](https://github.com/radar/forem), an engine that provides forum +functionality. There's also [Spree](https://github.com/spree/spree) which +provides an e-commerce platform, and +[RefineryCMS](https://github.com/refinery/refinerycms), a CMS engine. + +Finally, engines would not have been possible without the work of James Adam, +Piotr Sarnacki, the Rails Core Team, and a number of other people. If you ever +meet them, don't forget to say thanks! Generating an engine -------------------- -To generate an engine, you will need to run the plugin generator and pass it options as appropriate to the need. For the "blorgh" example, you will need to create a "mountable" engine, running this command in a terminal: +To generate an engine, you will need to run the plugin generator and pass it +options as appropriate to the need. For the "blorgh" example, you will need to +create a "mountable" engine, running this command in a terminal: ```bash $ rails plugin new blorgh --mountable @@ -47,7 +82,8 @@ The full list of options for the plugin generator may be seen by typing: $ rails plugin --help ``` -The `--full` option tells the generator that you want to create an engine, including a skeleton structure that provides the following: +The `--full` option tells the generator that you want to create an engine, +including a skeleton structure that provides the following: * An `app` directory tree * A `config/routes.rb` file: @@ -56,7 +92,9 @@ The `--full` option tells the generator that you want to create an engine, inclu Rails.application.routes.draw do end ``` - * A file at `lib/blorgh/engine.rb`, which is identical in function to a standard Rails application's `config/application.rb` file: + + * A file at `lib/blorgh/engine.rb`, which is identical in function to a + * standard Rails application's `config/application.rb` file: ```ruby module Blorgh @@ -65,7 +103,9 @@ The `--full` option tells the generator that you want to create an engine, inclu end ``` -The `--mountable` option tells the generator that you want to create a "mountable" and namespace-isolated engine. This generator will provide the same skeleton structure as would the `--full` option, and will add: +The `--mountable` option tells the generator that you want to create a +"mountable" and namespace-isolated engine. This generator will provide the same +skeleton structure as would the `--full` option, and will add: * Asset manifest files (`application.js` and `application.css`) * A namespaced `ApplicationController` stub @@ -88,7 +128,10 @@ The `--mountable` option tells the generator that you want to create a "mountabl end ``` -Additionally, the `--mountable` option tells the generator to mount the engine inside the dummy testing application located at `test/dummy` by adding the following to the dummy application's routes file at `test/dummy/config/routes.rb`: +Additionally, the `--mountable` option tells the generator to mount the engine +inside the dummy testing application located at `test/dummy` by adding the +following to the dummy application's routes file at +`test/dummy/config/routes.rb`: ```ruby mount Blorgh::Engine, at: "blorgh" @@ -98,13 +141,19 @@ mount Blorgh::Engine, at: "blorgh" #### Critical Files -At the root of this brand new engine's directory lives a `blorgh.gemspec` file. When you include the engine into an application later on, you will do so with this line in the Rails application's `Gemfile`: +At the root of this brand new engine's directory lives a `blorgh.gemspec` file. +When you include the engine into an application later on, you will do so with +this line in the Rails application's `Gemfile`: ```ruby gem 'blorgh', path: "vendor/engines/blorgh" ``` -Don't forget to run `bundle install` as usual. By specifying it as a gem within the `Gemfile`, Bundler will load it as such, parsing this `blorgh.gemspec` file and requiring a file within the `lib` directory called `lib/blorgh.rb`. This file requires the `blorgh/engine.rb` file (located at `lib/blorgh/engine.rb`) and defines a base module called `Blorgh`. +Don't forget to run `bundle install` as usual. By specifying it as a gem within +the `Gemfile`, Bundler will load it as such, parsing this `blorgh.gemspec` file +and requiring a file within the `lib` directory called `lib/blorgh.rb`. This +file requires the `blorgh/engine.rb` file (located at `lib/blorgh/engine.rb`) +and defines a base module called `Blorgh`. ```ruby require "blorgh/engine" @@ -113,7 +162,10 @@ module Blorgh end ``` -TIP: Some engines choose to use this file to put global configuration options for their engine. It's a relatively good idea, so if you want to offer configuration options, the file where your engine's `module` is defined is perfect for that. Place the methods inside the module and you'll be good to go. +TIP: Some engines choose to use this file to put global configuration options +for their engine. It's a relatively good idea, so if you want to offer +configuration options, the file where your engine's `module` is defined is +perfect for that. Place the methods inside the module and you'll be good to go. Within `lib/blorgh/engine.rb` is the base class for the engine: @@ -125,43 +177,94 @@ module Blorgh end ``` -By inheriting from the `Rails::Engine` class, this gem notifies Rails that there's an engine at the specified path, and will correctly mount the engine inside the application, performing tasks such as adding the `app` directory of the engine to the load path for models, mailers, controllers and views. - -The `isolate_namespace` method here deserves special notice. This call is responsible for isolating the controllers, models, routes and other things into their own namespace, away from similar components inside the application. Without this, there is a possibility that the engine's components could "leak" into the application, causing unwanted disruption, or that important engine components could be overridden by similarly named things within the application. One of the examples of such conflicts is helpers. Without calling `isolate_namespace`, the engine's helpers would be included in an application's controllers. - -NOTE: It is **highly** recommended that the `isolate_namespace` line be left within the `Engine` class definition. Without it, classes generated in an engine **may** conflict with an application. - -What this isolation of the namespace means is that a model generated by a call to `rails g model` such as `rails g model post` won't be called `Post`, but instead be namespaced and called `Blorgh::Post`. In addition, the table for the model is namespaced, becoming `blorgh_posts`, rather than simply `posts`. Similar to the model namespacing, a controller called `PostsController` becomes `Blorgh::PostsController` and the views for that controller will not be at `app/views/posts`, but `app/views/blorgh/posts` instead. Mailers are namespaced as well. - -Finally, routes will also be isolated within the engine. This is one of the most important parts about namespacing, and is discussed later in the [Routes](#routes) section of this guide. +By inheriting from the `Rails::Engine` class, this gem notifies Rails that +there's an engine at the specified path, and will correctly mount the engine +inside the application, performing tasks such as adding the `app` directory of +the engine to the load path for models, mailers, controllers and views. + +The `isolate_namespace` method here deserves special notice. This call is +responsible for isolating the controllers, models, routes and other things into +their own namespace, away from similar components inside the application. +Without this, there is a possibility that the engine's components could "leak" +into the application, causing unwanted disruption, or that important engine +components could be overridden by similarly named things within the application. +One of the examples of such conflicts is helpers. Without calling +`isolate_namespace`, the engine's helpers would be included in an application's +controllers. + +NOTE: It is **highly** recommended that the `isolate_namespace` line be left +within the `Engine` class definition. Without it, classes generated in an engine +**may** conflict with an application. + +What this isolation of the namespace means is that a model generated by a call +to `rails g model`, such as `rails g model post`, won't be called `Post`, but +instead be namespaced and called `Blorgh::Post`. In addition, the table for the +model is namespaced, becoming `blorgh_posts`, rather than simply `posts`. +Similar to the model namespacing, a controller called `PostsController` becomes +`Blorgh::PostsController` and the views for that controller will not be at +`app/views/posts`, but `app/views/blorgh/posts` instead. Mailers are namespaced +as well. + +Finally, routes will also be isolated within the engine. This is one of the most +important parts about namespacing, and is discussed later in the +[Routes](#routes) section of this guide. #### `app` Directory -Inside the `app` directory are the standard `assets`, `controllers`, `helpers`, `mailers`, `models` and `views` directories that you should be familiar with from an application. The `helpers`, `mailers` and `models` directories are empty, so they aren't described in this section. We'll look more into models in a future section, when we're writing the engine. - -Within the `app/assets` directory, there are the `images`, `javascripts` and `stylesheets` directories which, again, you should be familiar with due to their similarity to an application. One difference here, however, is that each directory contains a sub-directory with the engine name. Because this engine is going to be namespaced, its assets should be too. - -Within the `app/controllers` directory there is a `blorgh` directory that contains a file called `application_controller.rb`. This file will provide any common functionality for the controllers of the engine. The `blorgh` directory is where the other controllers for the engine will go. By placing them within this namespaced directory, you prevent them from possibly clashing with identically-named controllers within other engines or even within the application. - -NOTE: The `ApplicationController` class inside an engine is named just like a Rails application in order to make it easier for you to convert your applications into engines. - -Lastly, the `app/views` directory contains a `layouts` folder, which contains a file at `blorgh/application.html.erb`. This file allows you to specify a layout for the engine. If this engine is to be used as a stand-alone engine, then you would add any customization to its layout in this file, rather than the application's `app/views/layouts/application.html.erb` file. - -If you don't want to force a layout on to users of the engine, then you can delete this file and reference a different layout in the controllers of your engine. +Inside the `app` directory are the standard `assets`, `controllers`, `helpers`, +`mailers`, `models` and `views` directories that you should be familiar with +from an application. The `helpers`, `mailers` and `models` directories are +empty, so they aren't described in this section. We'll look more into models in +a future section, when we're writing the engine. + +Within the `app/assets` directory, there are the `images`, `javascripts` and +`stylesheets` directories which, again, you should be familiar with due to their +similarity to an application. One difference here, however, is that each +directory contains a sub-directory with the engine name. Because this engine is +going to be namespaced, its assets should be too. + +Within the `app/controllers` directory there is a `blorgh` directory that +contains a file called `application_controller.rb`. This file will provide any +common functionality for the controllers of the engine. The `blorgh` directory +is where the other controllers for the engine will go. By placing them within +this namespaced directory, you prevent them from possibly clashing with +identically-named controllers within other engines or even within the +application. + +NOTE: The `ApplicationController` class inside an engine is named just like a +Rails application in order to make it easier for you to convert your +applications into engines. + +Lastly, the `app/views` directory contains a `layouts` folder, which contains a +file at `blorgh/application.html.erb`. This file allows you to specify a layout +for the engine. If this engine is to be used as a stand-alone engine, then you +would add any customization to its layout in this file, rather than the +application's `app/views/layouts/application.html.erb` file. + +If you don't want to force a layout on to users of the engine, then you can +delete this file and reference a different layout in the controllers of your +engine. #### `bin` Directory -This directory contains one file, `bin/rails`, which enables you to use the `rails` sub-commands and generators just like you would within an application. This means that you will be able to generate new controllers and models for this engine very easily by running commands like this: +This directory contains one file, `bin/rails`, which enables you to use the +`rails` sub-commands and generators just like you would within an application. +This means that you will be able to generate new controllers and models for this +engine very easily by running commands like this: ```bash rails g model ``` -Keep in mind, of course, that anything generated with these commands inside of an engine that has `isolate_namespace` in the `Engine` class will be namespaced. +Keep in mind, of course, that anything generated with these commands inside of +an engine that has `isolate_namespace` in the `Engine` class will be namespaced. #### `test` Directory -The `test` directory is where tests for the engine will go. To test the engine, there is a cut-down version of a Rails application embedded within it at `test/dummy`. This application will mount the engine in the `test/dummy/config/routes.rb` file: +The `test` directory is where tests for the engine will go. To test the engine, +there is a cut-down version of a Rails application embedded within it at +`test/dummy`. This application will mount the engine in the +`test/dummy/config/routes.rb` file: ```ruby Rails.application.routes.draw do @@ -169,18 +272,25 @@ Rails.application.routes.draw do end ``` -This line mounts the engine at the path `/blorgh`, which will make it accessible through the application only at that path. +This line mounts the engine at the path `/blorgh`, which will make it accessible +through the application only at that path. -Inside the test directory there is the `test/integration` directory, where integration tests for the engine should be placed. Other directories can be created in the `test` directory as well. For example, you may wish to create a `test/models` directory for your model tests. +Inside the test directory there is the `test/integration` directory, where +integration tests for the engine should be placed. Other directories can be +created in the `test` directory as well. For example, you may wish to create a +`test/models` directory for your model tests. Providing engine functionality ------------------------------ -The engine that this guide covers provides posting and commenting functionality and follows a similar thread to the [Getting Started Guide](getting_started.html), with some new twists. +The engine that this guide covers provides posting and commenting functionality +and follows a similar thread to the [Getting Started +Guide](getting_started.html), with some new twists. ### Generating a Post Resource -The first thing to generate for a blog engine is the `Post` model and related controller. To quickly generate this, you can use the Rails scaffold generator. +The first thing to generate for a blog engine is the `Post` model and related +controller. To quickly generate this, you can use the Rails scaffold generator. ```bash $ rails generate scaffold post title:string text:text @@ -221,11 +331,22 @@ invoke css create app/assets/stylesheets/scaffold.css ``` -The first thing that the scaffold generator does is invoke the `active_record` generator, which generates a migration and a model for the resource. Note here, however, that the migration is called `create_blorgh_posts` rather than the usual `create_posts`. This is due to the `isolate_namespace` method called in the `Blorgh::Engine` class's definition. The model here is also namespaced, being placed at `app/models/blorgh/post.rb` rather than `app/models/post.rb` due to the `isolate_namespace` call within the `Engine` class. +The first thing that the scaffold generator does is invoke the `active_record` +generator, which generates a migration and a model for the resource. Note here, +however, that the migration is called `create_blorgh_posts` rather than the +usual `create_posts`. This is due to the `isolate_namespace` method called in +the `Blorgh::Engine` class's definition. The model here is also namespaced, +being placed at `app/models/blorgh/post.rb` rather than `app/models/post.rb` due +to the `isolate_namespace` call within the `Engine` class. -Next, the `test_unit` generator is invoked for this model, generating a model test at `test/models/blorgh/post_test.rb` (rather than `test/models/post_test.rb`) and a fixture at `test/fixtures/blorgh/posts.yml` (rather than `test/fixtures/posts.yml`). +Next, the `test_unit` generator is invoked for this model, generating a model +test at `test/models/blorgh/post_test.rb` (rather than +`test/models/post_test.rb`) and a fixture at `test/fixtures/blorgh/posts.yml` +(rather than `test/fixtures/posts.yml`). -After that, a line for the resource is inserted into the `config/routes.rb` file for the engine. This line is simply `resources :posts`, turning the `config/routes.rb` file for the engine into this: +After that, a line for the resource is inserted into the `config/routes.rb` file +for the engine. This line is simply `resources :posts`, turning the +`config/routes.rb` file for the engine into this: ```ruby Blorgh::Engine.routes.draw do @@ -233,12 +354,22 @@ Blorgh::Engine.routes.draw do end ``` -Note here that the routes are drawn upon the `Blorgh::Engine` object rather than the `YourApp::Application` class. This is so that the engine routes are confined to the engine itself and can be mounted at a specific point as shown in the [test directory](#test-directory) section. It also causes the engine's routes to be isolated from those routes that are within the application. The [Routes](#routes) section of -this guide describes it in detail. +Note here that the routes are drawn upon the `Blorgh::Engine` object rather than +the `YourApp::Application` class. This is so that the engine routes are confined +to the engine itself and can be mounted at a specific point as shown in the +[test directory](#test-directory) section. It also causes the engine's routes to +be isolated from those routes that are within the application. The +[Routes](#routes) section of this guide describes it in detail. -Next, the `scaffold_controller` generator is invoked, generating a controller called `Blorgh::PostsController` (at `app/controllers/blorgh/posts_controller.rb`) and its related views at `app/views/blorgh/posts`. This generator also generates a test for the controller (`test/controllers/blorgh/posts_controller_test.rb`) and a helper (`app/helpers/blorgh/posts_controller.rb`). +Next, the `scaffold_controller` generator is invoked, generating a controller +called `Blorgh::PostsController` (at +`app/controllers/blorgh/posts_controller.rb`) and its related views at +`app/views/blorgh/posts`. This generator also generates a test for the +controller (`test/controllers/blorgh/posts_controller_test.rb`) and a helper +(`app/helpers/blorgh/posts_controller.rb`). -Everything this generator has created is neatly namespaced. The controller's class is defined within the `Blorgh` module: +Everything this generator has created is neatly namespaced. The controller's +class is defined within the `Blorgh` module: ```ruby module Blorgh @@ -248,7 +379,8 @@ module Blorgh end ``` -NOTE: The `ApplicationController` class being inherited from here is the `Blorgh::ApplicationController`, not an application's `ApplicationController`. +NOTE: The `ApplicationController` class being inherited from here is the +`Blorgh::ApplicationController`, not an application's `ApplicationController`. The helper inside `app/helpers/blorgh/posts_helper.rb` is also namespaced: @@ -260,38 +392,63 @@ module Blorgh end ``` -This helps prevent conflicts with any other engine or application that may have a post resource as well. +This helps prevent conflicts with any other engine or application that may have +a post resource as well. -Finally, the assets for this resource are generated in two files: `app/assets/javascripts/blorgh/posts.js` and `app/assets/stylesheets/blorgh/posts.css`. You'll see how to use these a little later. +Finally, the assets for this resource are generated in two files: +`app/assets/javascripts/blorgh/posts.js` and +`app/assets/stylesheets/blorgh/posts.css`. You'll see how to use these a little +later. -By default, the scaffold styling is not applied to the engine because the engine's layout file, `app/views/layouts/blorgh/application.html.erb`, doesn't load it. To make the scaffold styling apply, insert this line into the `` tag of this layout: +By default, the scaffold styling is not applied to the engine because the +engine's layout file, `app/views/layouts/blorgh/application.html.erb`, doesn't +load it. To make the scaffold styling apply, insert this line into the `` +tag of this layout: ```erb <%= stylesheet_link_tag "scaffold" %> ``` -You can see what the engine has so far by running `rake db:migrate` at the root of our engine to run the migration generated by the scaffold generator, and then running `rails server` in `test/dummy`. When you open `http://localhost:3000/blorgh/posts` you will see the default scaffold that has been generated. Click around! You've just generated your first engine's first functions. +You can see what the engine has so far by running `rake db:migrate` at the root +of our engine to run the migration generated by the scaffold generator, and then +running `rails server` in `test/dummy`. When you open +`http://localhost:3000/blorgh/posts` you will see the default scaffold that has +been generated. Click around! You've just generated your first engine's first +functions. -If you'd rather play around in the console, `rails console` will also work just like a Rails application. Remember: the `Post` model is namespaced, so to reference it you must call it as `Blorgh::Post`. +If you'd rather play around in the console, `rails console` will also work just +like a Rails application. Remember: the `Post` model is namespaced, so to +reference it you must call it as `Blorgh::Post`. ```ruby >> Blorgh::Post.find(1) => # ``` -One final thing is that the `posts` resource for this engine should be the root of the engine. Whenever someone goes to the root path where the engine is mounted, they should be shown a list of posts. This can be made to happen if this line is inserted into the `config/routes.rb` file inside the engine: +One final thing is that the `posts` resource for this engine should be the root +of the engine. Whenever someone goes to the root path where the engine is +mounted, they should be shown a list of posts. This can be made to happen if +this line is inserted into the `config/routes.rb` file inside the engine: ```ruby root to: "posts#index" ``` -Now people will only need to go to the root of the engine to see all the posts, rather than visiting `/posts`. This means that instead of `http://localhost:3000/blorgh/posts`, you only need to go to `http://localhost:3000/blorgh` now. +Now people will only need to go to the root of the engine to see all the posts, +rather than visiting `/posts`. This means that instead of +`http://localhost:3000/blorgh/posts`, you only need to go to +`http://localhost:3000/blorgh` now. ### Generating a Comments Resource -Now that the engine can create new blog posts, it only makes sense to add commenting functionality as well. To do this, you'll need to generate a comment model, a comment controller and then modify the posts scaffold to display comments and allow people to create new ones. +Now that the engine can create new blog posts, it only makes sense to add +commenting functionality as well. To do this, you'll need to generate a comment +model, a comment controller and then modify the posts scaffold to display +comments and allow people to create new ones. -From the application root, run the model generator. Tell it to generate a `Comment` model, with the related table having two columns: a `post_id` integer and `text` text column. +From the application root, run the model generator. Tell it to generate a +`Comment` model, with the related table having two columns: a `post_id` integer +and `text` text column. ```bash $ rails generate model Comment post_id:integer text:text @@ -308,20 +465,26 @@ create test/models/blorgh/comment_test.rb create test/fixtures/blorgh/comments.yml ``` -This generator call will generate just the necessary model files it needs, namespacing the files under a `blorgh` directory and creating a model class called `Blorgh::Comment`. Now run the migration to create our blorgh_comments table: +This generator call will generate just the necessary model files it needs, +namespacing the files under a `blorgh` directory and creating a model class +called `Blorgh::Comment`. Now run the migration to create our blorgh_comments +table: ```bash $ rake db:migrate ``` -To show the comments on a post, edit `app/views/blorgh/posts/show.html.erb` and add this line before the "Edit" link: +To show the comments on a post, edit `app/views/blorgh/posts/show.html.erb` and +add this line before the "Edit" link: ```html+erb

    Comments

    <%= render @post.comments %> ``` -This line will require there to be a `has_many` association for comments defined on the `Blorgh::Post` model, which there isn't right now. To define one, open `app/models/blorgh/post.rb` and add this line into the model: +This line will require there to be a `has_many` association for comments defined +on the `Blorgh::Post` model, which there isn't right now. To define one, open +`app/models/blorgh/post.rb` and add this line into the model: ```ruby has_many :comments @@ -337,15 +500,22 @@ module Blorgh end ``` -NOTE: Because the `has_many` is defined inside a class that is inside the `Blorgh` module, Rails will know that you want to use the `Blorgh::Comment` model for these objects, so there's no need to specify that using the `:class_name` option here. +NOTE: Because the `has_many` is defined inside a class that is inside the +`Blorgh` module, Rails will know that you want to use the `Blorgh::Comment` +model for these objects, so there's no need to specify that using the +`:class_name` option here. -Next, there needs to be a form so that comments can be created on a post. To add this, put this line underneath the call to `render @post.comments` in `app/views/blorgh/posts/show.html.erb`: +Next, there needs to be a form so that comments can be created on a post. To add +this, put this line underneath the call to `render @post.comments` in +`app/views/blorgh/posts/show.html.erb`: ```erb <%= render "blorgh/comments/form" %> ``` -Next, the partial that this line will render needs to exist. Create a new directory at `app/views/blorgh/comments` and in it a new file called `_form.html.erb` which has this content to create the required partial: +Next, the partial that this line will render needs to exist. Create a new +directory at `app/views/blorgh/comments` and in it a new file called +`_form.html.erb` which has this content to create the required partial: ```html+erb

    New comment

    @@ -358,7 +528,10 @@ Next, the partial that this line will render needs to exist. Create a new direct <% end %> ``` -When this form is submitted, it is going to attempt to perform a `POST` request to a route of `/posts/:post_id/comments` within the engine. This route doesn't exist at the moment, but can be created by changing the `resources :posts` line inside `config/routes.rb` into these lines: +When this form is submitted, it is going to attempt to perform a `POST` request +to a route of `/posts/:post_id/comments` within the engine. This route doesn't +exist at the moment, but can be created by changing the `resources :posts` line +inside `config/routes.rb` into these lines: ```ruby resources :posts do @@ -368,7 +541,8 @@ end This creates a nested route for the comments, which is what the form requires. -The route now exists, but the controller that this route goes to does not. To create it, run this command from the application root: +The route now exists, but the controller that this route goes to does not. To +create it, run this command from the application root: ```bash $ rails g controller comments @@ -393,7 +567,10 @@ invoke css create app/assets/stylesheets/blorgh/comments.css ``` -The form will be making a `POST` request to `/posts/:post_id/comments`, which will correspond with the `create` action in `Blorgh::CommentsController`. This action needs to be created, which can be done by putting the following lines inside the class definition in `app/controllers/blorgh/comments_controller.rb`: +The form will be making a `POST` request to `/posts/:post_id/comments`, which +will correspond with the `create` action in `Blorgh::CommentsController`. This +action needs to be created, which can be done by putting the following lines +inside the class definition in `app/controllers/blorgh/comments_controller.rb`: ```ruby def create @@ -409,46 +586,66 @@ private end ``` -This is the final step required to get the new comment form working. Displaying the comments, however, is not quite right yet. If you were to create a comment right now, you would see this error: +This is the final step required to get the new comment form working. Displaying +the comments, however, is not quite right yet. If you were to create a comment +right now, you would see this error: -``` -Missing partial blorgh/comments/comment with {:handlers=>[:erb, :builder], :formats=>[:html], :locale=>[:en, :en]}. Searched in: - * "/Users/ryan/Sites/side_projects/blorgh/test/dummy/app/views" - * "/Users/ryan/Sites/side_projects/blorgh/app/views" +``` +Missing partial blorgh/comments/comment with {:handlers=>[:erb, :builder], +:formats=>[:html], :locale=>[:en, :en]}. Searched in: * +"/Users/ryan/Sites/side_projects/blorgh/test/dummy/app/views" * +"/Users/ryan/Sites/side_projects/blorgh/app/views" ``` -The engine is unable to find the partial required for rendering the comments. Rails looks first in the application's (`test/dummy`) `app/views` directory and then in the engine's `app/views` directory. When it can't find it, it will throw this error. The engine knows to look for `blorgh/comments/comment` because the model object it is receiving is from the `Blorgh::Comment` class. +The engine is unable to find the partial required for rendering the comments. +Rails looks first in the application's (`test/dummy`) `app/views` directory and +then in the engine's `app/views` directory. When it can't find it, it will throw +this error. The engine knows to look for `blorgh/comments/comment` because the +model object it is receiving is from the `Blorgh::Comment` class. -This partial will be responsible for rendering just the comment text, for now. Create a new file at `app/views/blorgh/comments/_comment.html.erb` and put this line inside it: +This partial will be responsible for rendering just the comment text, for now. +Create a new file at `app/views/blorgh/comments/_comment.html.erb` and put this +line inside it: ```erb <%= comment_counter + 1 %>. <%= comment.text %> ``` -The `comment_counter` local variable is given to us by the `<%= render @post.comments %>` call, which will define it automatically and increment the counter as it iterates through each comment. It's used in this example to display a small number next to each comment when it's created. +The `comment_counter` local variable is given to us by the `<%= render +@post.comments %>` call, which will define it automatically and increment the +counter as it iterates through each comment. It's used in this example to +display a small number next to each comment when it's created. -That completes the comment function of the blogging engine. Now it's time to use it within an application. +That completes the comment function of the blogging engine. Now it's time to use +it within an application. Hooking Into an Application --------------------------- -Using an engine within an application is very easy. This section covers how to mount the engine into an application and the initial setup required, as well as linking the engine to a `User` class provided by the application to provide ownership for posts and comments within the engine. +Using an engine within an application is very easy. This section covers how to +mount the engine into an application and the initial setup required, as well as +linking the engine to a `User` class provided by the application to provide +ownership for posts and comments within the engine. ### Mounting the Engine -First, the engine needs to be specified inside the application's `Gemfile`. If there isn't an application handy to test this out in, generate one using the `rails new` command outside of the engine directory like this: +First, the engine needs to be specified inside the application's `Gemfile`. If +there isn't an application handy to test this out in, generate one using the +`rails new` command outside of the engine directory like this: ```bash $ rails new unicorn ``` -Usually, specifying the engine inside the Gemfile would be done by specifying it as a normal, everyday gem. +Usually, specifying the engine inside the Gemfile would be done by specifying it +as a normal, everyday gem. ```ruby gem 'devise' ``` -However, because you are developing the `blorgh` engine on your local machine, you will need to specify the `:path` option in your `Gemfile`: +However, because you are developing the `blorgh` engine on your local machine, +you will need to specify the `:path` option in your `Gemfile`: ```ruby gem 'blorgh', path: "/path/to/blorgh" @@ -456,50 +653,76 @@ gem 'blorgh', path: "/path/to/blorgh" Then run `bundle` to install the gem. -As described earlier, by placing the gem in the `Gemfile` it will be loaded when Rails is loaded. It will first require `lib/blorgh.rb` from the engine, then `lib/blorgh/engine.rb`, which is the file that defines the major pieces of functionality for the engine. +As described earlier, by placing the gem in the `Gemfile` it will be loaded when +Rails is loaded. It will first require `lib/blorgh.rb` from the engine, then +`lib/blorgh/engine.rb`, which is the file that defines the major pieces of +functionality for the engine. -To make the engine's functionality accessible from within an application, it needs to be mounted in that application's `config/routes.rb` file: +To make the engine's functionality accessible from within an application, it +needs to be mounted in that application's `config/routes.rb` file: ```ruby mount Blorgh::Engine, at: "/blog" ``` -This line will mount the engine at `/blog` in the application. Making it accessible at `http://localhost:3000/blog` when the application runs with `rails server`. +This line will mount the engine at `/blog` in the application. Making it +accessible at `http://localhost:3000/blog` when the application runs with `rails +server`. -NOTE: Other engines, such as Devise, handle this a little differently by making you specify custom helpers (such as `devise_for`) in the routes. These helpers do exactly the same thing, mounting pieces of the engines's functionality at a pre-defined path which may be customizable. +NOTE: Other engines, such as Devise, handle this a little differently by making +you specify custom helpers (such as `devise_for`) in the routes. These helpers +do exactly the same thing, mounting pieces of the engines's functionality at a +pre-defined path which may be customizable. ### Engine setup -The engine contains migrations for the `blorgh_posts` and `blorgh_comments` table which need to be created in the application's database so that the engine's models can query them correctly. To copy these migrations into the application use this command: +The engine contains migrations for the `blorgh_posts` and `blorgh_comments` +table which need to be created in the application's database so that the +engine's models can query them correctly. To copy these migrations into the +application use this command: ```bash $ rake blorgh:install:migrations ``` -If you have multiple engines that need migrations copied over, use `railties:install:migrations` instead: +If you have multiple engines that need migrations copied over, use +`railties:install:migrations` instead: ```bash $ rake railties:install:migrations ``` -This command, when run for the first time, will copy over all the migrations from the engine. When run the next time, it will only copy over migrations that haven't been copied over already. The first run for this command will output something such as this: +This command, when run for the first time, will copy over all the migrations +from the engine. When run the next time, it will only copy over migrations that +haven't been copied over already. The first run for this command will output +something such as this: ```bash Copied migration [timestamp_1]_create_blorgh_posts.rb from blorgh Copied migration [timestamp_2]_create_blorgh_comments.rb from blorgh ``` -The first timestamp (`[timestamp_1]`) will be the current time, and the second timestamp (`[timestamp_2]`) will be the current time plus a second. The reason for this is so that the migrations for the engine are run after any existing migrations in the application. +The first timestamp (`[timestamp_1]`) will be the current time, and the second +timestamp (`[timestamp_2]`) will be the current time plus a second. The reason +for this is so that the migrations for the engine are run after any existing +migrations in the application. -To run these migrations within the context of the application, simply run `rake db:migrate`. When accessing the engine through `http://localhost:3000/blog`, the posts will be empty. This is because the table created inside the application is different from the one created within the engine. Go ahead, play around with the newly mounted engine. You'll find that it's the same as when it was only an engine. +To run these migrations within the context of the application, simply run `rake +db:migrate`. When accessing the engine through `http://localhost:3000/blog`, the +posts will be empty. This is because the table created inside the application is +different from the one created within the engine. Go ahead, play around with the +newly mounted engine. You'll find that it's the same as when it was only an +engine. -If you would like to run migrations only from one engine, you can do it by specifying `SCOPE`: +If you would like to run migrations only from one engine, you can do it by +specifying `SCOPE`: ```bash rake db:migrate SCOPE=blorgh ``` -This may be useful if you want to revert engine's migrations before removing it. To revert all migrations from blorgh engine you can run code such as: +This may be useful if you want to revert engine's migrations before removing it. +To revert all migrations from blorgh engine you can run code such as: ```bash rake db:migrate SCOPE=blorgh VERSION=0 @@ -509,21 +732,36 @@ rake db:migrate SCOPE=blorgh VERSION=0 #### Using a Model Provided by the Application -When an engine is created, it may want to use specific classes from an application to provide links between the pieces of the engine and the pieces of the application. In the case of the `blorgh` engine, making posts and comments have authors would make a lot of sense. +When an engine is created, it may want to use specific classes from an +application to provide links between the pieces of the engine and the pieces of +the application. In the case of the `blorgh` engine, making posts and comments +have authors would make a lot of sense. -A typical application might have a `User` class that would be used to represent authors for a post or a comment. But there could be a case where the application calls this class something different, such as `Person`. For this reason, the engine should not hardcode associations specifically for a `User` class. +A typical application might have a `User` class that would be used to represent +authors for a post or a comment. But there could be a case where the application +calls this class something different, such as `Person`. For this reason, the +engine should not hardcode associations specifically for a `User` class. -To keep it simple in this case, the application will have a class called `User` that represents the users of the application. It can be generated using this command inside the application: +To keep it simple in this case, the application will have a class called `User` +that represents the users of the application. It can be generated using this +command inside the application: ```bash rails g model user name:string ``` -The `rake db:migrate` command needs to be run here to ensure that our application has the `users` table for future use. +The `rake db:migrate` command needs to be run here to ensure that our +application has the `users` table for future use. -Also, to keep it simple, the posts form will have a new text field called `author_name`, where users can elect to put their name. The engine will then take this name and either create a new `User` object from it, or find one that already has that name. The engine will then associate the post with the found or created `User` object. +Also, to keep it simple, the posts form will have a new text field called +`author_name`, where users can elect to put their name. The engine will then +take this name and either create a new `User` object from it, or find one that +already has that name. The engine will then associate the post with the found or +created `User` object. -First, the `author_name` text field needs to be added to the `app/views/blorgh/posts/_form.html.erb` partial inside the engine. This can be added above the `title` field with this code: +First, the `author_name` text field needs to be added to the +`app/views/blorgh/posts/_form.html.erb` partial inside the engine. This can be +added above the `title` field with this code: ```html+erb
    @@ -532,7 +770,8 @@ First, the `author_name` text field needs to be added to the `app/views/blorgh/p
    ``` -Next, we need to update our `Blorgh::PostController#post_params` method to permit the new form parameter: +Next, we need to update our `Blorgh::PostController#post_params` method to +permit the new form parameter: ```ruby def post_params @@ -540,9 +779,15 @@ def post_params end ``` -The `Blorgh::Post` model should then have some code to convert the `author_name` field into an actual `User` object and associate it as that post's `author` before the post is saved. It will also need to have an `attr_accessor` set up for this field, so that the setter and getter methods are defined for it. +The `Blorgh::Post` model should then have some code to convert the `author_name` +field into an actual `User` object and associate it as that post's `author` +before the post is saved. It will also need to have an `attr_accessor` set up +for this field, so that the setter and getter methods are defined for it. -To do all this, you'll need to add the `attr_accessor` for `author_name`, the association for the author and the `before_save` call into `app/models/blorgh/post.rb`. The `author` association will be hard-coded to the `User` class for the time being. +To do all this, you'll need to add the `attr_accessor` for `author_name`, the +association for the author and the `before_save` call into +`app/models/blorgh/post.rb`. The `author` association will be hard-coded to the +`User` class for the time being. ```ruby attr_accessor :author_name @@ -556,7 +801,11 @@ private end ``` -By representing the `author` association's object with the `User` class, a link is established between the engine and the application. There needs to be a way of associating the records in the `blorgh_posts` table with the records in the `users` table. Because the association is called `author`, there should be an `author_id` column added to the `blorgh_posts` table. +By representing the `author` association's object with the `User` class, a link +is established between the engine and the application. There needs to be a way +of associating the records in the `blorgh_posts` table with the records in the +`users` table. Because the association is called `author`, there should be an +`author_id` column added to the `blorgh_posts` table. To generate this new column, run this command within the engine: @@ -564,20 +813,27 @@ To generate this new column, run this command within the engine: $ rails g migration add_author_id_to_blorgh_posts author_id:integer ``` -NOTE: Due to the migration's name and the column specification after it, Rails will automatically know that you want to add a column to a specific table and write that into the migration for you. You don't need to tell it any more than this. +NOTE: Due to the migration's name and the column specification after it, Rails +will automatically know that you want to add a column to a specific table and +write that into the migration for you. You don't need to tell it any more than +this. -This migration will need to be run on the application. To do that, it must first be copied using this command: +This migration will need to be run on the application. To do that, it must first +be copied using this command: ```bash $ rake blorgh:install:migrations ``` -Notice that only _one_ migration was copied over here. This is because the first two migrations were copied over the first time this command was run. +Notice that only _one_ migration was copied over here. This is because the first +two migrations were copied over the first time this command was run. -``` -NOTE Migration [timestamp]_create_blorgh_posts.rb from blorgh has been skipped. Migration with the same name already exists. -NOTE Migration [timestamp]_create_blorgh_comments.rb from blorgh has been skipped. Migration with the same name already exists. -Copied migration [timestamp]_add_author_id_to_blorgh_posts.rb from blorgh +``` +NOTE Migration [timestamp]_create_blorgh_posts.rb from blorgh has been +skipped. Migration with the same name already exists. NOTE Migration +[timestamp]_create_blorgh_comments.rb from blorgh has been skipped. Migration +with the same name already exists. Copied migration +[timestamp]_add_author_id_to_blorgh_posts.rb from blorgh ``` Run the migration using: @@ -586,9 +842,12 @@ Run the migration using: $ rake db:migrate ``` -Now with all the pieces in place, an action will take place that will associate an author - represented by a record in the `users` table - with a post, represented by the `blorgh_posts` table from the engine. +Now with all the pieces in place, an action will take place that will associate +an author - represented by a record in the `users` table - with a post, +represented by the `blorgh_posts` table from the engine. -Finally, the author's name should be displayed on the post's page. Add this code above the "Title" output inside `app/views/blorgh/posts/show.html.erb`: +Finally, the author's name should be displayed on the post's page. Add this code +above the "Title" output inside `app/views/blorgh/posts/show.html.erb`: ```html+erb

    @@ -597,13 +856,15 @@ Finally, the author's name should be displayed on the post's page. Add this code

    ``` -By outputting `@post.author` using the `<%=` tag, the `to_s` method will be called on the object. By default, this will look quite ugly: +By outputting `@post.author` using the `<%=` tag, the `to_s` method will be +called on the object. By default, this will look quite ugly: ``` # ``` -This is undesirable. It would be much better to have the user's name there. To do this, add a `to_s` method to the `User` class within the application: +This is undesirable. It would be much better to have the user's name there. To +do this, add a `to_s` method to the `User` class within the application: ```ruby def to_s @@ -615,34 +876,58 @@ Now instead of the ugly Ruby object output, the author's name will be displayed. #### Using a Controller Provided by the Application -Because Rails controllers generally share code for things like authentication and accessing session variables, they inherit from `ApplicationController` by default. Rails engines, however are scoped to run independently from the main application, so each engine gets a scoped `ApplicationController`. This namespace prevents code collisions, but often engine controllers need to access methods in the main application's `ApplicationController`. An easy way to provide this access is to change the engine's scoped `ApplicationController` to inherit from the main application's `ApplicationController`. For our Blorgh engine this would be done by changing `app/controllers/blorgh/application_controller.rb` to look like: +Because Rails controllers generally share code for things like authentication +and accessing session variables, they inherit from `ApplicationController` by +default. Rails engines, however are scoped to run independently from the main +application, so each engine gets a scoped `ApplicationController`. This +namespace prevents code collisions, but often engine controllers need to access +methods in the main application's `ApplicationController`. An easy way to +provide this access is to change the engine's scoped `ApplicationController` to +inherit from the main application's `ApplicationController`. For our Blorgh +engine this would be done by changing +`app/controllers/blorgh/application_controller.rb` to look like: ```ruby class Blorgh::ApplicationController < ApplicationController end ``` -By default, the engine's controllers inherit from `Blorgh::ApplicationController`. So, after making this change they will have access to the main application's `ApplicationController`, as though they were part of the main application. +By default, the engine's controllers inherit from +`Blorgh::ApplicationController`. So, after making this change they will have +access to the main application's `ApplicationController`, as though they were +part of the main application. -This change does require that the engine is run from a Rails application that has an `ApplicationController`. +This change does require that the engine is run from a Rails application that +has an `ApplicationController`. ### Configuring an Engine -This section covers how to make the `User` class configurable, followed by general configuration tips for the engine. +This section covers how to make the `User` class configurable, followed by +general configuration tips for the engine. #### Setting Configuration Settings in the Application -The next step is to make the class that represents a `User` in the application customizable for the engine. This is because that class may not always be `User`, as previously explained. To make this setting customizable, the engine will have a configuration setting called `author_class` that will be used to specify which class represents users inside the application. +The next step is to make the class that represents a `User` in the application +customizable for the engine. This is because that class may not always be +`User`, as previously explained. To make this setting customizable, the engine +will have a configuration setting called `author_class` that will be used to +specify which class represents users inside the application. -To define this configuration setting, you should use a `mattr_accessor` inside the `Blorgh` module for the engine. Add this line to `lib/blorgh.rb` inside the engine: +To define this configuration setting, you should use a `mattr_accessor` inside +the `Blorgh` module for the engine. Add this line to `lib/blorgh.rb` inside the +engine: ```ruby mattr_accessor :author_class ``` -This method works like its brothers, `attr_accessor` and `cattr_accessor`, but provides a setter and getter method on the module with the specified name. To use it, it must be referenced using `Blorgh.author_class`. +This method works like its brothers, `attr_accessor` and `cattr_accessor`, but +provides a setter and getter method on the module with the specified name. To +use it, it must be referenced using `Blorgh.author_class`. -The next step is to switch the `Blorgh::Post` model over to this new setting. Change the `belongs_to` association inside this model (`app/models/blorgh/post.rb`) to this: +The next step is to switch the `Blorgh::Post` model over to this new setting. +Change the `belongs_to` association inside this model +(`app/models/blorgh/post.rb`) to this: ```ruby belongs_to :author, class_name: Blorgh.author_class @@ -654,7 +939,10 @@ The `set_author` method in the `Blorgh::Post` model should also use this class: self.author = Blorgh.author_class.constantize.find_or_create_by(name: author_name) ``` -To save having to call `constantize` on the `author_class` result all the time, you could instead just override the `author_class` getter method inside the `Blorgh` module in the `lib/blorgh.rb` file to always call `constantize` on the saved value before returning the result: +To save having to call `constantize` on the `author_class` result all the time, +you could instead just override the `author_class` getter method inside the +`Blorgh` module in the `lib/blorgh.rb` file to always call `constantize` on the +saved value before returning the result: ```ruby def self.author_class @@ -668,82 +956,123 @@ This would then turn the above code for `set_author` into this: self.author = Blorgh.author_class.find_or_create_by(name: author_name) ``` -Resulting in something a little shorter, and more implicit in its behavior. The `author_class` method should always return a `Class` object. +Resulting in something a little shorter, and more implicit in its behavior. The +`author_class` method should always return a `Class` object. -Since we changed the `author_class` method to no longer return a -`String` but a `Class` we must also modify our `belongs_to` definition -in the `Blorgh::Post` model: +Since we changed the `author_class` method to return a `String` instead of a +`Class`, we must also modify our `belongs_to` definition in the `Blorgh::Post` +model: ```ruby belongs_to :author, class_name: Blorgh.author_class.to_s ``` -To set this configuration setting within the application, an initializer should be used. By using an initializer, the configuration will be set up before the application starts and calls the engine's models, which may depend on this configuration setting existing. +To set this configuration setting within the application, an initializer should +be used. By using an initializer, the configuration will be set up before the +application starts and calls the engine's models, which may depend on this +configuration setting existing. -Create a new initializer at `config/initializers/blorgh.rb` inside the application where the `blorgh` engine is installed and put this content in it: +Create a new initializer at `config/initializers/blorgh.rb` inside the +application where the `blorgh` engine is installed and put this content in it: ```ruby Blorgh.author_class = "User" ``` -WARNING: It's very important here to use the `String` version of the class, rather than the class itself. If you were to use the class, Rails would attempt to load that class and then reference the related table. This could lead to problems if the table wasn't already existing. Therefore, a `String` should be used and then converted to a class using `constantize` in the engine later on. +WARNING: It's very important here to use the `String` version of the class, +rather than the class itself. If you were to use the class, Rails would attempt +to load that class and then reference the related table. This could lead to +problems if the table wasn't already existing. Therefore, a `String` should be +used and then converted to a class using `constantize` in the engine later on. -Go ahead and try to create a new post. You will see that it works exactly in the same way as before, except this time the engine is using the configuration setting in `config/initializers/blorgh.rb` to learn what the class is. +Go ahead and try to create a new post. You will see that it works exactly in the +same way as before, except this time the engine is using the configuration +setting in `config/initializers/blorgh.rb` to learn what the class is. -There are now no strict dependencies on what the class is, only what the API for the class must be. The engine simply requires this class to define a `find_or_create_by` method which returns an object of that class, to be associated with a post when it's created. This object, of course, should have some sort of identifier by which it can be referenced. +There are now no strict dependencies on what the class is, only what the API for +the class must be. The engine simply requires this class to define a +`find_or_create_by` method which returns an object of that class, to be +associated with a post when it's created. This object, of course, should have +some sort of identifier by which it can be referenced. #### General Engine Configuration -Within an engine, there may come a time where you wish to use things such as initializers, internationalization or other configuration options. The great news is that these things are entirely possible, because a Rails engine shares much the same functionality as a Rails application. In fact, a Rails application's functionality is actually a superset of what is provided by engines! +Within an engine, there may come a time where you wish to use things such as +initializers, internationalization or other configuration options. The great +news is that these things are entirely possible, because a Rails engine shares +much the same functionality as a Rails application. In fact, a Rails +application's functionality is actually a superset of what is provided by +engines! If you wish to use an initializer - code that should run before the engine is loaded - the place for it is the `config/initializers` folder. This directory's -functionality is explained in the -[Initializers section](configuring.html#initializers) of the Configuring guide, -and works precisely the same way as the `config/initializers` directory inside -an application. Same goes for if you want to use a standard initializer. +functionality is explained in the [Initializers +section](configuring.html#initializers) of the Configuring guide, and works +precisely the same way as the `config/initializers` directory inside an +application. The same thing goes if you want to use a standard initializer. -For locales, simply place the locale files in the `config/locales` directory, just like you would in an application. +For locales, simply place the locale files in the `config/locales` directory, +just like you would in an application. -Testing an engine ------------------ +Testing an engine ----------------- -When an engine is generated, there is a smaller dummy application created inside it at `test/dummy`. This application is used as a mounting point for the engine, to make testing the engine extremely simple. You may extend this application by generating controllers, models or views from within the directory, and then use those to test your engine. +When an engine is generated, there is a smaller dummy application created inside +it at `test/dummy`. This application is used as a mounting point for the engine, +to make testing the engine extremely simple. You may extend this application by +generating controllers, models or views from within the directory, and then use +those to test your engine. -The `test` directory should be treated like a typical Rails testing environment, allowing for unit, functional and integration tests. +The `test` directory should be treated like a typical Rails testing environment, +allowing for unit, functional and integration tests. ### Functional Tests -A matter worth taking into consideration when writing functional tests is that the tests are going to be running on an application - the `test/dummy` application - rather than your engine. This is due to the setup of the testing environment; an engine needs an application as a host for testing its main functionality, especially controllers. This means that if you were to make a typical `GET` to a controller in a controller's functional test like this: +A matter worth taking into consideration when writing functional tests is that +the tests are going to be running on an application - the `test/dummy` +application - rather than your engine. This is due to the setup of the testing +environment; an engine needs an application as a host for testing its main +functionality, especially controllers. This means that if you were to make a +typical `GET` to a controller in a controller's functional test like this: ```ruby get :index ``` -It may not function correctly. This is because the application doesn't know how to route these requests to the engine unless you explicitly tell it **how**. To do this, you must also pass the `:use_route` option as a parameter on these requests: +It may not function correctly. This is because the application doesn't know how +to route these requests to the engine unless you explicitly tell it **how**. To +do this, you must also pass the `:use_route` option as a parameter on these +requests: ```ruby get :index, use_route: :blorgh ``` -This tells the application that you still want to perform a `GET` request to the `index` action of this controller, but you want to use the engine's route to get there, rather than the application's one. +This tells the application that you still want to perform a `GET` request to the +`index` action of this controller, but you want to use the engine's route to get +there, rather than the application's one. Improving engine functionality ------------------------------ -This section explains how to add and/or override engine MVC functionality in the main Rails application. +This section explains how to add and/or override engine MVC functionality in the +main Rails application. ### Overriding Models and Controllers -Engine model and controller classes can be extended by open classing them in the main Rails application (since model and controller classes are just Ruby classes that inherit Rails specific functionality). Open classing an Engine class redefines it for use in the main application. This is usually implemented by using the decorator pattern. +Engine model and controller classes can be extended by open classing them in the +main Rails application (since model and controller classes are just Ruby classes +that inherit Rails specific functionality). Open classing an Engine class +redefines it for use in the main application. This is usually implemented by +using the decorator pattern. -For simple class modifications, use `Class#class_eval`. For complex class modifications, consider using `ActiveSupport::Concern`. +For simple class modifications, use `Class#class_eval`. For complex class +modifications, consider using `ActiveSupport::Concern`. #### A note on Decorators and Loading Code Because these decorators are not referenced by your Rails application itself, -Rails' autoloading system will not kick in and load your decorators. This -means that you need to require them yourself. +Rails' autoloading system will not kick in and load your decorators. This means +that you need to require them yourself. Here is some sample code to do this: @@ -813,7 +1142,11 @@ end #### Implementing Decorator Pattern Using ActiveSupport::Concern -Using `Class#class_eval` is great for simple adjustments, but for more complex class modifications, you might want to consider using [`ActiveSupport::Concern`](http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html). ActiveSupport::Concern manages load order of interlinked dependent modules and classes at run time allowing you to significantly modularize your code. +Using `Class#class_eval` is great for simple adjustments, but for more complex +class modifications, you might want to consider using [`ActiveSupport::Concern`] +(http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html). +ActiveSupport::Concern manages load order of interlinked dependent modules and +classes at run time allowing you to significantly modularize your code. **Adding** `Post#time_since_created` and **Overriding** `Post#summary`: @@ -876,13 +1209,21 @@ end ### Overriding Views -When Rails looks for a view to render, it will first look in the `app/views` directory of the application. If it cannot find the view there, it will check in the `app/views` directories of all engines that have this directory. +When Rails looks for a view to render, it will first look in the `app/views` +directory of the application. If it cannot find the view there, it will check in +the `app/views` directories of all engines that have this directory. -When the application is asked to render the view for `Blorgh::PostsController`'s index action, it will first look for the path `app/views/blorgh/posts/index.html.erb` within the application. If it cannot find it, it will look inside the engine. +When the application is asked to render the view for `Blorgh::PostsController`'s +index action, it will first look for the path +`app/views/blorgh/posts/index.html.erb` within the application. If it cannot +find it, it will look inside the engine. -You can override this view in the application by simply creating a new file at `app/views/blorgh/posts/index.html.erb`. Then you can completely change what this view would normally output. +You can override this view in the application by simply creating a new file at +`app/views/blorgh/posts/index.html.erb`. Then you can completely change what +this view would normally output. -Try this now by creating a new file at `app/views/blorgh/posts/index.html.erb` and put this content in it: +Try this now by creating a new file at `app/views/blorgh/posts/index.html.erb` +and put this content in it: ```html+erb

    Posts

    @@ -897,9 +1238,13 @@ Try this now by creating a new file at `app/views/blorgh/posts/index.html.erb` a ### Routes -Routes inside an engine are isolated from the application by default. This is done by the `isolate_namespace` call inside the `Engine` class. This essentially means that the application and its engines can have identically named routes and they will not clash. +Routes inside an engine are isolated from the application by default. This is +done by the `isolate_namespace` call inside the `Engine` class. This essentially +means that the application and its engines can have identically named routes and +they will not clash. -Routes inside an engine are drawn on the `Engine` class within `config/routes.rb`, like this: +Routes inside an engine are drawn on the `Engine` class within +`config/routes.rb`, like this: ```ruby Blorgh::Engine.routes.draw do @@ -907,43 +1252,71 @@ Blorgh::Engine.routes.draw do end ``` -By having isolated routes such as this, if you wish to link to an area of an engine from within an application, you will need to use the engine's routing proxy method. Calls to normal routing methods such as `posts_path` may end up going to undesired locations if both the application and the engine have such a helper defined. +By having isolated routes such as this, if you wish to link to an area of an +engine from within an application, you will need to use the engine's routing +proxy method. Calls to normal routing methods such as `posts_path` may end up +going to undesired locations if both the application and the engine have such a +helper defined. -For instance, the following example would go to the application's `posts_path` if that template was rendered from the application, or the engine's `posts_path` if it was rendered from the engine: +For instance, the following example would go to the application's `posts_path` +if that template was rendered from the application, or the engine's `posts_path` +if it was rendered from the engine: ```erb <%= link_to "Blog posts", posts_path %> ``` -To make this route always use the engine's `posts_path` routing helper method, we must call the method on the routing proxy method that shares the same name as the engine. +To make this route always use the engine's `posts_path` routing helper method, +we must call the method on the routing proxy method that shares the same name as +the engine. ```erb <%= link_to "Blog posts", blorgh.posts_path %> ``` -If you wish to reference the application inside the engine in a similar way, use the `main_app` helper: +If you wish to reference the application inside the engine in a similar way, use +the `main_app` helper: ```erb <%= link_to "Home", main_app.root_path %> ``` -If you were to use this inside an engine, it would **always** go to the application's root. If you were to leave off the `main_app` "routing proxy" method call, it could potentially go to the engine's or application's root, depending on where it was called from. +If you were to use this inside an engine, it would **always** go to the +application's root. If you were to leave off the `main_app` "routing proxy" +method call, it could potentially go to the engine's or application's root, +depending on where it was called from. -If a template rendered from within an engine attempts to use one of the application's routing helper methods, it may result in an undefined method call. If you encounter such an issue, ensure that you're not attempting to call the application's routing methods without the `main_app` prefix from within the engine. +If a template rendered from within an engine attempts to use one of the +application's routing helper methods, it may result in an undefined method call. +If you encounter such an issue, ensure that you're not attempting to call the +application's routing methods without the `main_app` prefix from within the +engine. ### Assets -Assets within an engine work in an identical way to a full application. Because the engine class inherits from `Rails::Engine`, the application will know to look up assets in the engine's 'app/assets' and 'lib/assets' directories. +Assets within an engine work in an identical way to a full application. Because +the engine class inherits from `Rails::Engine`, the application will know to +look up assets in the engine's 'app/assets' and 'lib/assets' directories. -Like all of the other components of an engine, the assets should be namespaced. This means that if you have an asset called `style.css`, it should be placed at `app/assets/stylesheets/[engine name]/style.css`, rather than `app/assets/stylesheets/style.css`. If this asset isn't namespaced, there is a possibility that the host application could have an asset named identically, in which case the application's asset would take precedence and the engine's one would be ignored. +Like all of the other components of an engine, the assets should be namespaced. +This means that if you have an asset called `style.css`, it should be placed at +`app/assets/stylesheets/[engine name]/style.css`, rather than +`app/assets/stylesheets/style.css`. If this asset isn't namespaced, there is a +possibility that the host application could have an asset named identically, in +which case the application's asset would take precedence and the engine's one +would be ignored. -Imagine that you did have an asset located at `app/assets/stylesheets/blorgh/style.css` To include this asset inside an application, just use `stylesheet_link_tag` and reference the asset as if it were inside the engine: +Imagine that you did have an asset located at +`app/assets/stylesheets/blorgh/style.css` To include this asset inside an +application, just use `stylesheet_link_tag` and reference the asset as if it +were inside the engine: ```erb <%= stylesheet_link_tag "blorgh/style.css" %> ``` -You can also specify these assets as dependencies of other assets using Asset Pipeline require statements in processed files: +You can also specify these assets as dependencies of other assets using Asset +Pipeline require statements in processed files: ``` /* @@ -951,14 +1324,19 @@ You can also specify these assets as dependencies of other assets using Asset Pi */ ``` -INFO. Remember that in order to use languages like Sass or CoffeeScript, you should add the relevant library to your engine's `.gemspec`. +INFO. Remember that in order to use languages like Sass or CoffeeScript, you +should add the relevant library to your engine's `.gemspec`. ### Separate Assets & Precompiling -There are some situations where your engine's assets are not required by the host application. For example, say that you've created -an admin functionality that only exists for your engine. In this case, the host application doesn't need to require `admin.css` -or `admin.js`. Only the gem's admin layout needs these assets. It doesn't make sense for the host app to include `"blorgh/admin.css"` in its stylesheets. In this situation, you should explicitly define these assets for precompilation. -This tells sprockets to add your engine assets when `rake assets:precompile` is triggered. +There are some situations where your engine's assets are not required by the +host application. For example, say that you've created an admin functionality +that only exists for your engine. In this case, the host application doesn't +need to require `admin.css` or `admin.js`. Only the gem's admin layout needs +these assets. It doesn't make sense for the host app to include +`"blorgh/admin.css"` in its stylesheets. In this situation, you should +explicitly define these assets for precompilation. This tells sprockets to add +your engine assets when `rake assets:precompile` is triggered. You can define assets for precompilation in `engine.rb`: @@ -972,11 +1350,11 @@ For more information, read the [Asset Pipeline guide](asset_pipeline.html). ### Other Gem Dependencies -Gem dependencies inside an engine should be specified inside the -`.gemspec` file at the root of the engine. The reason is that the engine may -be installed as a gem. If dependencies were to be specified inside the `Gemfile`, -these would not be recognized by a traditional gem install and so they would not -be installed, causing the engine to malfunction. +Gem dependencies inside an engine should be specified inside the `.gemspec` file +at the root of the engine. The reason is that the engine may be installed as a +gem. If dependencies were to be specified inside the `Gemfile`, these would not +be recognized by a traditional gem install and so they would not be installed, +causing the engine to malfunction. To specify a dependency that should be installed with the engine during a traditional `gem install`, specify it inside the `Gem::Specification` block @@ -986,7 +1364,7 @@ inside the `.gemspec` file in the engine: s.add_dependency "moo" ``` -To specify a dependency that should only be installed as a development +To specify a dependency that should only be installed as a development dependency of the application, specify it like this: ```ruby @@ -994,11 +1372,12 @@ s.add_development_dependency "moo" ``` Both kinds of dependencies will be installed when `bundle install` is run inside -the application. The development dependencies for the gem will only be used when -the tests for the engine are running. +of the application. The development dependencies for the gem will only be used +when the tests for the engine are running. Note that if you want to immediately require dependencies when the engine is -required, you should require them before the engine's initialization. For example: +required, you should require them before the engine's initialization. For +example: ```ruby require 'other_engine/engine' -- cgit v1.2.3 From 8d005eb8671851ada381f1e521d7f11aa874dc12 Mon Sep 17 00:00:00 2001 From: schneems Date: Sat, 14 Dec 2013 12:44:54 -0800 Subject: [ci skip] add `assets.raise_runtime_errors` flag The flag will be used in multiple places to check for errors during runtime if enabled. Source: https://github.com/rails/sprockets-rails/pull/100 --- guides/source/configuring.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'guides/source') diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 8ac34c9716..add8ec10a7 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -136,7 +136,9 @@ numbers. New applications filter out passwords by adding the following `config.f * `config.assets.enabled` a flag that controls whether the asset pipeline is enabled. It is set to true by default. -* `config.assets.compress` a flag that enables the compression of compiled assets. It is explicitly set to true in `config/production.rb`. +*`config.assets.raise_runtime_errors`* Set this flag to `true` to enable additional runtime error checking. Recommended in `config/environments/development.rb` to minimize unexpected behavior when deploying to `production`. + +* `config.assets.compress` a flag that enables the compression of compiled assets. It is explicitly set to true in `config/environments/production.rb`. * `config.assets.css_compressor` defines the CSS compressor to use. It is set by default by `sass-rails`. The unique alternative value at the moment is `:yui`, which uses the `yui-compressor` gem. @@ -775,7 +777,7 @@ error similar to given below will be thrown. ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5 seconds. The max pool size is currently 5; consider increasing it: ``` -If you get the above error, you might want to increase the size of connection +If you get the above error, you might want to increase the size of connection pool by incrementing the `pool` option in `database.yml` NOTE. If you have enabled `Rails.threadsafe!` mode then there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited amount of connections. -- cgit v1.2.3 From c758093eca303704f52b45fd0660e13600b9b315 Mon Sep 17 00:00:00 2001 From: Akshay Vishnoi Date: Mon, 16 Dec 2013 00:44:37 +0530 Subject: Spelling and Grammar check [ci skip] --- guides/source/generators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/generators.md b/guides/source/generators.md index e9c8ef0225..4a5377c206 100644 --- a/guides/source/generators.md +++ b/guides/source/generators.md @@ -560,7 +560,7 @@ This method also takes a block: ```ruby vendor "seeds.rb" do - "puts 'in ur app, seeding ur database'" + "puts 'in your app, seeding your database'" end ``` -- cgit v1.2.3 From e838fa068f230682ee9a1114119c81061a308508 Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 16 Dec 2013 10:13:35 +0300 Subject: Added `absence` parameter to pluralization table Added `absence` parameter to table in section `5.1.2 Error Message Interpolation`. --- guides/source/i18n.md | 1 + 1 file changed, 1 insertion(+) (limited to 'guides/source') diff --git a/guides/source/i18n.md b/guides/source/i18n.md index 6f79b3ddd7..a98ef567ea 100644 --- a/guides/source/i18n.md +++ b/guides/source/i18n.md @@ -833,6 +833,7 @@ So, for example, instead of the default error message `"can not be blank"` you c | confirmation | - | :confirmation | - | | acceptance | - | :accepted | - | | presence | - | :blank | - | +| absence | - | :present | - | | length | :within, :in | :too_short | count | | length | :within, :in | :too_long | count | | length | :is | :wrong_length | count | -- cgit v1.2.3 From 80dbcf629c2d6a28109edafb15c144c3f83e8be8 Mon Sep 17 00:00:00 2001 From: Jacob Evan Shreve Date: Mon, 16 Dec 2013 13:43:50 -0500 Subject: Fix url leak in application templates guide Encapsulate url that was including the trailing quote and colon. --- guides/source/rails_application_templates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md index 711d910184..70e7c97b8a 100644 --- a/guides/source/rails_application_templates.md +++ b/guides/source/rails_application_templates.md @@ -78,7 +78,7 @@ end Adds the given source to the generated application's `Gemfile`. -For example, if you need to source a gem from "http://code.whytheluckystiff.net": +For example, if you need to source a gem from "[http://code.whytheluckystiff.net](http://code.whytheluckystiff.net)": ```ruby add_source "http://code.whytheluckystiff.net" -- cgit v1.2.3 From 0dea33f770305f32ed7476f520f7c1ff17434fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 16 Dec 2013 16:57:35 -0200 Subject: Remove the link for code.whytheluckystiff.net This is not a valid URL. [ci skip] --- guides/source/rails_application_templates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md index 70e7c97b8a..e4222e1283 100644 --- a/guides/source/rails_application_templates.md +++ b/guides/source/rails_application_templates.md @@ -78,7 +78,7 @@ end Adds the given source to the generated application's `Gemfile`. -For example, if you need to source a gem from "[http://code.whytheluckystiff.net](http://code.whytheluckystiff.net)": +For example, if you need to source a gem from `"http://code.whytheluckystiff.net"`: ```ruby add_source "http://code.whytheluckystiff.net" -- cgit v1.2.3 From eeda62eac4c8f1e7584ba20da9bc365211b88edb Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Tue, 17 Dec 2013 09:43:19 +0100 Subject: use `bin/spring` in release notes. [ci skip] Follow up to: https://github.com/rails/rails/commit/828a8f214535e59d709fd4862605902d1cc21632#commitcomment-4879462 This will be available after https://github.com/jonleighton/spring/commit/c6e25804b3338959d87a29f40967a333c650c031 is released. --- guides/source/4_1_release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 3126f4e0e1..1e36327b78 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -101,7 +101,7 @@ bin/rails console **spring introspection:** ``` -$ bundle exec spring status +$ bin/spring status Spring is running: 1182 spring server | my_app | started 29 mins ago -- cgit v1.2.3 From 798da61825cb3ba8a44b8a9bf8cb984acd373332 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Tue, 17 Dec 2013 11:18:50 +0100 Subject: minor doc reword. Upgrade Rails itself not to Rails. [ci skip] /cc @chancancode --- guides/source/4_0_release_notes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'guides/source') diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md index c0eb77c1e7..19c690233c 100644 --- a/guides/source/4_0_release_notes.md +++ b/guides/source/4_0_release_notes.md @@ -15,7 +15,7 @@ These release notes cover only the major changes. To know about various bug fixe Upgrading to Rails 4.0 ---------------------- -If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 3.2 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 4.0. A list of things to watch out for when upgrading is available in the [Upgrading to Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-3-2-to-rails-4-0) guide. +If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 3.2 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 4.0. A list of things to watch out for when upgrading is available in the [Upgrading Ruby on Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-3-2-to-rails-4-0) guide. Creating a Rails 4.0 application @@ -90,7 +90,7 @@ Major Features * **match do not catch all** ([commit](https://github.com/rails/rails/commit/90d2802b71a6e89aedfe40564a37bd35f777e541)) - In the routing DSL, match requires the HTTP verb or verbs to be specified. * **html entities escaped by default** ([commit](https://github.com/rails/rails/commit/5f189f41258b83d49012ec5a0678d827327e7543)) - Strings rendered in erb are escaped unless wrapped with `raw` or `html_safe` is called. * **New security headers** ([commit](https://github.com/rails/rails/commit/6794e92b204572d75a07bd6413bdae6ae22d5a82)) - Rails sends the following headers with every HTTP request: `X-Frame-Options` (prevents clickjacking by forbidding the browser from embedding the page in a frame), `X-XSS-Protection` (asks the browser to halt script injection) and `X-Content-Type-Options` (prevents the browser from opening a jpeg as an exe). - + Extraction of features to gems --------------------------- @@ -268,7 +268,7 @@ Please refer to the [Changelog](https://github.com/rails/rails/blob/4-0-stable/a * `scoped_by_...` can be rewritten using `where(...)`. * `find_or_initialize_by_...` can be rewritten using `find_or_initialize_by(...)`. * `find_or_create_by_...` can be rewritten using `find_or_create_by(...)`. - * `find_or_create_by_...!` can be rewritten using `find_or_create_by!(...)`. + * `find_or_create_by_...!` can be rewritten using `find_or_create_by!(...)`. Credits ------- -- cgit v1.2.3 From 8e21ae37ad9fef6b7393a84f9b5f2e18a831e49a Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Mon, 16 Dec 2013 17:12:37 -0200 Subject: Add changelog and upgrading notice related to I18n enforce_available_locales handling --- guides/source/upgrading_ruby_on_rails.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'guides/source') diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index ca5623bf73..1c233b4d82 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -156,6 +156,23 @@ end ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers ``` +### I18n enforcing available locales + +Rails 4.1 now defaults the I18n option `enforce_available_locales` to `true`, +meaning that it will make sure that all locales passed to it must be declared in +the `available_locales` list. + +To disable it (and allow I18n to accept *any* locale option) add the following +configuration to your application: + +```ruby +config.i18n.enforce_available_locales = false +``` + +Note that this option was added as a security measure, to ensure user input could +not be used as locale information unless previously known, so it's recommended not +to disable this option unless you have a strong reason for doing so. + Upgrading from Rails 3.2 to Rails 4.0 ------------------------------------- -- cgit v1.2.3 From 998550396f1911d830a8d52f71972030064a1a9e Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Tue, 17 Dec 2013 12:17:13 +0100 Subject: release notes link to fixed versions of the API. [ci skip] As discussed with @fxn the release notes are a snapshot document. The links going out to the API should represent that exact snapshot. This means we always link to the full final release. For example the 3.2 release notes link to http://api.rubyonrails.org/v3.2.0. --- guides/source/3_1_release_notes.md | 2 +- guides/source/4_1_release_notes.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'guides/source') diff --git a/guides/source/3_1_release_notes.md b/guides/source/3_1_release_notes.md index 5c99892e39..485f8c756b 100644 --- a/guides/source/3_1_release_notes.md +++ b/guides/source/3_1_release_notes.md @@ -286,7 +286,7 @@ Action Pack end ``` - You can restrict it to some actions by using `:only` or `:except`. Please read the docs at [`ActionController::Streaming`](http://api.rubyonrails.org/classes/ActionController/Streaming.html) for more information. + You can restrict it to some actions by using `:only` or `:except`. Please read the docs at [`ActionController::Streaming`](http://api.rubyonrails.org/v3.1.0/classes/ActionController/Streaming.html) for more information. * The redirect route method now also accepts a hash of options which will only change the parts of the url in question, or an object which responds to call, allowing for redirects to be reused. diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 1e36327b78..1a76968139 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -131,7 +131,7 @@ Conversation.archived # => Relation for all archived Conversations ``` See -[active_record/enum.rb](https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/enum.rb#L2-L42) +[active_record/enum.rb](api.rubyonrails.org/v4.1.0/classes/ActiveRecord/Enum.html) for a detailed write up. ### Application message verifier. -- cgit v1.2.3 From d4ee09cda135da9c36a5ddadd2d8c2d35c116be3 Mon Sep 17 00:00:00 2001 From: Lauro Caetano Date: Fri, 13 Dec 2013 22:11:39 -0200 Subject: Create a blacklist to disallow mutator methods to be delegated to `Array`. This change was necessary because the whitelist wouldn't work. It would be painful for users trying to update their applications. This blacklist intent to prevent odd bugs and confusion in code that call mutator methods directely on the `Relation`. --- guides/source/upgrading_ruby_on_rails.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'guides/source') diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index ca5623bf73..60b27aa6e5 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -156,6 +156,23 @@ end ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers ``` +### Mutator methods called on Relation + +`Relation` no longer has mutator methods like `#map!` and `#delete_if`. Convert +to an `Array` by calling `#to_a` before using these methods. + +It intends to prevent odd bugs and confusion in code that call mutator +methods directly on the `Relation`. + +```ruby +# Instead of this +Author.where(name: 'Hank Moody').compact! + +# Now you have to do this +authors = Author.where(name: 'Hank Moody').to_a +authors.compact! +``` + Upgrading from Rails 3.2 to Rails 4.0 ------------------------------------- -- cgit v1.2.3 From 2003d0409e357c7be8a9380f479d8094efc47d31 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Mon, 16 Dec 2013 22:08:58 -0800 Subject: Some assorted fixes for the 4.1 release notes: * Added release notes for secrets.yml and mentioned it in the highlights * Added release notes for Mailer previews and mentioned it in the highlights * Added release notes for Module#concerning * Removed mention for AV extraction from the highlights * Rearranged the major features to put highlighted features first * Various improvements and typo fixes [ci skip] --- guides/source/4_1_release_notes.md | 163 ++++++++++++++++++++++--------- guides/source/upgrading_ruby_on_rails.md | 27 +++++ 2 files changed, 145 insertions(+), 45 deletions(-) (limited to 'guides/source') diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 1a76968139..ebeda1d25e 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -3,9 +3,10 @@ Ruby on Rails 4.1 Release Notes Highlights in Rails 4.1: -* Variants -* Spring -* Action View extracted from Action Pack +* Spring application preloader +* `config/secrets.yml` +* Action Pack variants +* Action Mailer previews These release notes cover only the major changes. To know about various bug fixes and changes, please refer to the change logs or check out the @@ -22,14 +23,84 @@ coverage before going in. You should also first upgrade to Rails 4.0 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 4.1. A list of things to watch out for when upgrading is available in the -[Upgrading to Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-4-0-to-rails-4-1) +[Upgrading Ruby on Rails](upgrading_ruby_on_rails.html#upgrading-from-rails-4-0-to-rails-4-1) guide. Major Features -------------- -### Variants +### Spring application preloader + +Spring is a Rails application preloader. It speeds up development by keeping +your application running in the background so you don't need to boot it every +time you run a test, rake task or migration. + +New Rails 4.1 applications will ship with "springified" binstubs. This means +that `bin/rails` and `bin/rake` will automatically take advantage of preloaded +spring environments. + +**running rake tasks:** + +``` +bin/rake routes +``` + +**running tests:** + +``` +bin/rake test +bin/rake test test/models +bin/rake test test/models/user_test.rb +``` + +**running a console:** + +``` +bin/rails console +``` + +**spring introspection:** + +``` +$ bin/spring status +Spring is running: + + 1182 spring server | my_app | started 29 mins ago + 3656 spring app | my_app | started 23 secs ago | test mode + 3746 spring app | my_app | started 10 secs ago | development mode +``` + +Have a look at the +[Spring README](https://github.com/jonleighton/spring/blob/master/README.md) to +see all available features. + +See the [Upgrading Ruby on Rails](upgrading_ruby_on_rails.html#spring) +guide on how to migrate existing applications to use this feature. + +### `config/secrets.yml` + +Rails 4.1 will generate a new `secrets.yml` file in the `config` folder for new +applications. By default, this file contains the application's `secret_key_base`, +but it could also be used to store other secrets such as access keys for external +APIs. + +The secrets added to this file will be accessible via `Rails.application.secrets`. +For example, with the following `secrets.yml`: + +```yaml +development: + secret_key_base: 3b7cd727ee24e8444053437c36cc66c3 + some_api_key: SOMEKEY +``` + +`Rails.application.secrets.some_api_key` will return `SOMEKEY` in the development +environment. + +See the [Upgrading Ruby on Rails](upgrading_ruby_on_rails.html#config-secrets-yml) +guide on how to migrate existing applications to use this feature. + +### Action Pack variants We often want to render different html/json/xml templates for phones, tablets, and desktop browsers. Variants makes it easy. @@ -37,7 +108,7 @@ tablets, and desktop browsers. Variants makes it easy. The request variant is a specialization of the request format, like `:tablet`, `:phone`, or `:desktop`. -You can set the variant in a before_action: +You can set the variant in a `before_action`: ```ruby request.variant = :tablet if request.user_agent =~ /iPad/ @@ -72,46 +143,25 @@ respond_to do |format| end ``` -### Spring - -New Rails 4.1 applications will ship with "springified" binstubs. This means -that `bin/rails` and `bin/rake` will automatically take advantage preloaded -spring environments. - -**running rake tasks:** - -``` -bin/rake routes -``` - -**running tests:** +### Action Mailer previews -``` -bin/rake test -bin/rake test test/models -bin/rake test test/models/user_test.rb -``` - -**running a console:** - -``` -bin/rails console -``` - -**spring introspection:** +Preview email templates in the browser without delivering them. +```ruby +class NotifierPreview < ActionMailer::Preview + # Accessible from http://localhost:3000/rails/mailers/notifier/welcome + def welcome + Notifier.welcome(User.first) + end +end ``` -$ bin/spring status -Spring is running: - 1182 spring server | my_app | started 29 mins ago - 3656 spring app | my_app | started 23 secs ago | test mode - 3746 spring app | my_app | started 10 secs ago | development mode -``` +By default, these preview files live in test/mailers/previews. +This can be configured using the preview_path option. -Have a look at the -[Spring README](https://github.com/jonleighton/spring/blob/master/README.md) to -see a all available features. +See +[action_mailer/base.rb](api.rubyonrails.org/v4.1.0/classes/ActionMailer/Base.html) +for a detailed write up. ### Active Record enums @@ -123,7 +173,7 @@ class Conversation < ActiveRecord::Base enum status: [ :active, :archived ] end -conversation.archive! +conversation.archived! conversation.active? # => false conversation.status # => "archived" @@ -134,7 +184,7 @@ See [active_record/enum.rb](api.rubyonrails.org/v4.1.0/classes/ActiveRecord/Enum.html) for a detailed write up. -### Application message verifier. +### Application message verifier Create a message verifier that can be used to generate and verify signed messages in the application. @@ -145,9 +195,32 @@ Rails.application.message_verifier('salt').verify(message) # => 'my sensible data' ``` -Documentation -------------- +### Module#concerning + +A natural, low-ceremony way to separate responsibilities within a class: + +```ruby +class Todo < ActiveRecord::Base + concerning :EventTracking do + included do + has_many :events + end + + def latest_event + ... + end + + private + def some_internal_method + ... + end + end +end +``` +This example is equivalent to defining a `EventTracking` module inline, +extending it with `ActiveSupport::Concern`, then mixing it in to the +`Todo` class. Railties -------- diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index ca5623bf73..a7946b2120 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -39,6 +39,33 @@ NOTE: User defined rake tasks will run in the `development` environment by default. If you want them to run in other environments consult the [Spring README](https://github.com/jonleighton/spring#rake). +### `config/secrets.yml` + +If you want to use the new `secrets.yml` convention to store your application's +secrets, you need to: + +1. Create a `secrets.yml` file in your `config` folder with the following content: + + ```yaml + development: + secret_key_base: + + test: + secret_key_base: + + production: + secret_key_base: + ``` + +2. Copy the existing `secret_key_base` from the `secret_token.rb` initializer to + `secrets.yml` under the `production` section. + +3. Remove the `secret_token.rb` initializer. + +4. Use `rake secret` to generate new keys for the `development` and `test` sections. + +5. Restart your server. + ### Changes in JSON handling The are a few major changes related to JSON handling in Rails 4.1. -- cgit v1.2.3 From 1650bb3d56897cfef4c7e6b86a36eed4f1a41df5 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 12 Dec 2013 20:41:14 -0700 Subject: CSRF protection from cross-origin