diff options
Diffstat (limited to 'guides/source')
-rw-r--r-- | guides/source/active_record_basics.md | 17 | ||||
-rw-r--r-- | guides/source/active_record_callbacks.md | 34 | ||||
-rw-r--r-- | guides/source/active_record_migrations.md | 38 | ||||
-rw-r--r-- | guides/source/active_record_postgresql.md | 30 | ||||
-rw-r--r-- | guides/source/active_record_querying.md | 48 | ||||
-rw-r--r-- | guides/source/active_record_validations.md | 108 | ||||
-rw-r--r-- | guides/source/active_support_core_extensions.md | 16 | ||||
-rw-r--r-- | guides/source/association_basics.md | 26 | ||||
-rw-r--r-- | guides/source/configuring.md | 2 | ||||
-rw-r--r-- | guides/source/engines.md | 18 | ||||
-rw-r--r-- | guides/source/getting_started.md | 4 | ||||
-rw-r--r-- | guides/source/initialization.md | 12 | ||||
-rw-r--r-- | guides/source/plugins.md | 35 | ||||
-rw-r--r-- | guides/source/security.md | 4 | ||||
-rw-r--r-- | guides/source/testing.md | 44 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.md | 2 | ||||
-rw-r--r-- | guides/source/working_with_javascript_in_rails.md | 4 |
17 files changed, 230 insertions, 212 deletions
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md index dafbe17bbd..8bd135ddd5 100644 --- a/guides/source/active_record_basics.md +++ b/guides/source/active_record_basics.md @@ -132,10 +132,10 @@ Creating Active Record Models ----------------------------- It is very easy to create Active Record models. All you have to do is to -subclass the `ActiveRecord::Base` class and you're good to go: +subclass the `ApplicationRecord` class and you're good to go: ```ruby -class Product < ActiveRecord::Base +class Product < ApplicationRecord end ``` @@ -168,11 +168,12 @@ What if you need to follow a different naming convention or need to use your Rails application with a legacy database? No problem, you can easily override the default conventions. -You can use the `ActiveRecord::Base.table_name=` method to specify the table -name that should be used: +`ApplicationRecord` inherits from `ActionController::Base`, which defines a +number of helpful methods. You can use the `ActiveRecord::Base.table_name=` +method to specify the table name that should be used: ```ruby -class Product < ActiveRecord::Base +class Product < ApplicationRecord self.table_name = "my_products" end ``` @@ -193,7 +194,7 @@ It's also possible to override the column that should be used as the table's primary key using the `ActiveRecord::Base.primary_key=` method: ```ruby -class Product < ActiveRecord::Base +class Product < ApplicationRecord self.primary_key = "product_id" end ``` @@ -320,7 +321,7 @@ they raise the exception `ActiveRecord::RecordInvalid` if validation fails. A quick example to illustrate: ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord validates :name, presence: true end @@ -350,7 +351,7 @@ database that Active Record supports using `rake`. Here's a migration that creates a table: ```ruby -class CreatePublications < ActiveRecord::Migration +class CreatePublications < ActiveRecord::Migration[5.0] def change create_table :publications do |t| t.string :title diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md index b5ad3e9411..d95c6c0e78 100644 --- a/guides/source/active_record_callbacks.md +++ b/guides/source/active_record_callbacks.md @@ -31,7 +31,7 @@ Callbacks are methods that get called at certain moments of an object's life cyc In order to use the available callbacks, you need to register them. You can implement the callbacks as ordinary methods and use a macro-style class method to register them as callbacks: ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord validates :login, :email, presence: true before_validation :ensure_login_has_a_value @@ -48,7 +48,7 @@ end The macro-style class methods can also receive a block. Consider using this style if the code inside your block is so short that it fits in a single line: ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord validates :login, :email, presence: true before_create do @@ -60,7 +60,7 @@ end Callbacks can also be registered to only fire on certain life cycle events: ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord before_validation :normalize_name, on: :create # :on takes an array as well @@ -126,7 +126,7 @@ The `after_find` callback will be called whenever Active Record loads a record f The `after_initialize` and `after_find` callbacks have no `before_*` counterparts, but they can be registered just like the other Active Record callbacks. ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord after_initialize do |user| puts "You have initialized an object!" end @@ -151,7 +151,7 @@ You have initialized an object! The `after_touch` callback will be called whenever an Active Record object is touched. ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord after_touch do |user| puts "You have touched an object" end @@ -168,14 +168,14 @@ You have touched an object It can be used along with `belongs_to`: ```ruby -class Employee < ActiveRecord::Base +class Employee < ApplicationRecord belongs_to :company, touch: true after_touch do puts 'An Employee was touched' end end -class Company < ActiveRecord::Base +class Company < ApplicationRecord has_many :employees after_touch :log_when_employees_or_company_touched @@ -266,11 +266,11 @@ Relational Callbacks Callbacks work through model relationships, and can even be defined by them. Suppose an example where a user has many articles. A user's articles should be destroyed if the user is destroyed. Let's add an `after_destroy` callback to the `User` model by way of its relationship to the `Article` model: ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord has_many :articles, dependent: :destroy end -class Article < ActiveRecord::Base +class Article < ApplicationRecord after_destroy :log_destroy_action def log_destroy_action @@ -297,7 +297,7 @@ As with validations, we can also make the calling of a callback method condition You can associate the `:if` and `:unless` options with a symbol corresponding to the name of a predicate method that will get called right before the callback. When using the `:if` option, the callback won't be executed if the predicate method returns false; when using the `:unless` option, the callback won't be executed if the predicate method returns true. This is the most common option. Using this form of registration it is also possible to register several different predicates that should be called to check if the callback should be executed. ```ruby -class Order < ActiveRecord::Base +class Order < ApplicationRecord before_save :normalize_card_number, if: :paid_with_card? end ``` @@ -307,7 +307,7 @@ end You can also use a string that will be evaluated using `eval` and hence needs to contain valid Ruby code. You should use this option only when the string represents a really short condition: ```ruby -class Order < ActiveRecord::Base +class Order < ApplicationRecord before_save :normalize_card_number, if: "paid_with_card?" end ``` @@ -317,7 +317,7 @@ end Finally, it is possible to associate `:if` and `:unless` with a `Proc` object. This option is best suited when writing short validation methods, usually one-liners: ```ruby -class Order < ActiveRecord::Base +class Order < ApplicationRecord before_save :normalize_card_number, if: Proc.new { |order| order.paid_with_card? } end @@ -328,7 +328,7 @@ end When writing conditional callbacks, it is possible to mix both `:if` and `:unless` in the same callback declaration: ```ruby -class Comment < ActiveRecord::Base +class Comment < ApplicationRecord after_create :send_email_to_author, if: :author_wants_emails?, unless: Proc.new { |comment| comment.article.ignore_comments? } end @@ -354,7 +354,7 @@ end When declared inside a class, as above, the callback methods will receive the model object as a parameter. We can now use the callback class in the model: ```ruby -class PictureFile < ActiveRecord::Base +class PictureFile < ApplicationRecord after_destroy PictureFileCallbacks.new end ``` @@ -374,7 +374,7 @@ end If the callback method is declared this way, it won't be necessary to instantiate a `PictureFileCallbacks` object. ```ruby -class PictureFile < ActiveRecord::Base +class PictureFile < ApplicationRecord after_destroy PictureFileCallbacks end ``` @@ -398,7 +398,7 @@ end By using the `after_commit` callback we can account for this case. ```ruby -class PictureFile < ActiveRecord::Base +class PictureFile < ApplicationRecord after_commit :delete_picture_file_from_disk, on: [:destroy] def delete_picture_file_from_disk @@ -420,7 +420,7 @@ common, there are aliases for those operations: * `after_destroy_commit` ```ruby -class PictureFile < ActiveRecord::Base +class PictureFile < ApplicationRecord after_destroy_commit :delete_picture_file_from_disk def delete_picture_file_from_disk diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md index 5aa5dc4f60..a8ffa5b378 100644 --- a/guides/source/active_record_migrations.md +++ b/guides/source/active_record_migrations.md @@ -35,7 +35,7 @@ history to the latest version. Active Record will also update your Here's an example of a migration: ```ruby -class CreateProducts < ActiveRecord::Migration +class CreateProducts < ActiveRecord::Migration[5.0] def change create_table :products do |t| t.string :name @@ -72,7 +72,7 @@ If you wish for a migration to do something that Active Record doesn't know how to reverse, you can use `reversible`: ```ruby -class ChangeProductsPrice < ActiveRecord::Migration +class ChangeProductsPrice < ActiveRecord::Migration[5.0] def change reversible do |dir| change_table :products do |t| @@ -87,7 +87,7 @@ end Alternatively, you can use `up` and `down` instead of `change`: ```ruby -class ChangeProductsPrice < ActiveRecord::Migration +class ChangeProductsPrice < ActiveRecord::Migration[5.0] def up change_table :products do |t| t.change :price, :string @@ -129,7 +129,7 @@ $ bin/rails generate migration AddPartNumberToProducts This will create an empty but appropriately named migration: ```ruby -class AddPartNumberToProducts < ActiveRecord::Migration +class AddPartNumberToProducts < ActiveRecord::Migration[5.0] def change end end @@ -146,7 +146,7 @@ $ bin/rails generate migration AddPartNumberToProducts part_number:string will generate ```ruby -class AddPartNumberToProducts < ActiveRecord::Migration +class AddPartNumberToProducts < ActiveRecord::Migration[5.0] def change add_column :products, :part_number, :string end @@ -162,7 +162,7 @@ $ bin/rails generate migration AddPartNumberToProducts part_number:string:index will generate ```ruby -class AddPartNumberToProducts < ActiveRecord::Migration +class AddPartNumberToProducts < ActiveRecord::Migration[5.0] def change add_column :products, :part_number, :string add_index :products, :part_number @@ -180,7 +180,7 @@ $ bin/rails generate migration RemovePartNumberFromProducts part_number:string generates ```ruby -class RemovePartNumberFromProducts < ActiveRecord::Migration +class RemovePartNumberFromProducts < ActiveRecord::Migration[5.0] def change remove_column :products, :part_number, :string end @@ -196,7 +196,7 @@ $ bin/rails generate migration AddDetailsToProducts part_number:string price:dec generates ```ruby -class AddDetailsToProducts < ActiveRecord::Migration +class AddDetailsToProducts < ActiveRecord::Migration[5.0] def change add_column :products, :part_number, :string add_column :products, :price, :decimal @@ -215,7 +215,7 @@ $ bin/rails generate migration CreateProducts name:string part_number:string generates ```ruby -class CreateProducts < ActiveRecord::Migration +class CreateProducts < ActiveRecord::Migration[5.0] def change create_table :products do |t| t.string :name @@ -239,7 +239,7 @@ $ bin/rails generate migration AddUserRefToProducts user:references generates ```ruby -class AddUserRefToProducts < ActiveRecord::Migration +class AddUserRefToProducts < ActiveRecord::Migration[5.0] def change add_reference :products, :user, index: true, foreign_key: true end @@ -257,7 +257,7 @@ $ bin/rails g migration CreateJoinTableCustomerProduct customer product will produce the following migration: ```ruby -class CreateJoinTableCustomerProduct < ActiveRecord::Migration +class CreateJoinTableCustomerProduct < ActiveRecord::Migration[5.0] def change create_join_table :customers, :products do |t| # t.index [:customer_id, :product_id] @@ -281,7 +281,7 @@ $ bin/rails generate model Product name:string description:text will create a migration that looks like this ```ruby -class CreateProducts < ActiveRecord::Migration +class CreateProducts < ActiveRecord::Migration[5.0] def change create_table :products do |t| t.string :name @@ -309,7 +309,7 @@ $ bin/rails generate migration AddDetailsToProducts 'price:decimal{5,2}' supplie will produce a migration that looks like this ```ruby -class AddDetailsToProducts < ActiveRecord::Migration +class AddDetailsToProducts < ActiveRecord::Migration[5.0] def change add_column :products, :price, :decimal, precision: 5, scale: 2 add_reference :products, :supplier, polymorphic: true, index: true @@ -563,7 +563,7 @@ to reverse. You can use `reversible` to specify what to do when running a migration and what else to do when reverting it. For example: ```ruby -class ExampleMigration < ActiveRecord::Migration +class ExampleMigration < ActiveRecord::Migration[5.0] def change create_table :distributors do |t| t.string :zipcode @@ -616,7 +616,7 @@ is wise to perform the transformations in precisely the reverse order they were made in the `up` method. The example in the `reversible` section is equivalent to: ```ruby -class ExampleMigration < ActiveRecord::Migration +class ExampleMigration < ActiveRecord::Migration[5.0] def up create_table :distributors do |t| t.string :zipcode @@ -659,7 +659,7 @@ You can use Active Record's ability to rollback migrations using the `revert` me ```ruby require_relative '20121212123456_example_migration' -class FixupExampleMigration < ActiveRecord::Migration +class FixupExampleMigration < ActiveRecord::Migration[5.0] def change revert ExampleMigration @@ -677,7 +677,7 @@ is later decided it would be best to use Active Record validations, in place of the `CHECK` constraint, to verify the zipcode. ```ruby -class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration +class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration[5.0] def change revert do # copy-pasted code from ExampleMigration @@ -841,7 +841,7 @@ Several methods are provided in migrations that allow you to control all this: For example, this migration: ```ruby -class CreateProducts < ActiveRecord::Migration +class CreateProducts < ActiveRecord::Migration[5.0] def change suppress_messages do create_table :products do |t| @@ -1015,7 +1015,7 @@ to add or modify data. This is useful in an existing database that can't be dest and recreated, such as a production database. ```ruby -class AddInitialProducts < ActiveRecord::Migration +class AddInitialProducts < ActiveRecord::Migration[5.0] def up 5.times do |i| Product.create(name: "Product ##{i}", description: "A product.") diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md index 742db7be32..b592209d4b 100644 --- a/guides/source/active_record_postgresql.md +++ b/guides/source/active_record_postgresql.md @@ -39,7 +39,7 @@ create_table :documents do |t| end # app/models/document.rb -class Document < ActiveRecord::Base +class Document < ApplicationRecord end # Usage @@ -63,7 +63,7 @@ add_index :books, :tags, using: 'gin' add_index :books, :ratings, using: 'gin' # app/models/book.rb -class Book < ActiveRecord::Base +class Book < ApplicationRecord end # Usage @@ -97,7 +97,7 @@ ActiveRecord::Schema.define do end # app/models/profile.rb -class Profile < ActiveRecord::Base +class Profile < ApplicationRecord end # Usage @@ -122,7 +122,7 @@ create_table :events do |t| end # app/models/event.rb -class Event < ActiveRecord::Base +class Event < ApplicationRecord end # Usage @@ -150,7 +150,7 @@ create_table :events do |t| end # app/models/event.rb -class Event < ActiveRecord::Base +class Event < ApplicationRecord end # Usage @@ -200,7 +200,7 @@ create_table :contacts do |t| end # app/models/contact.rb -class Contact < ActiveRecord::Base +class Contact < ApplicationRecord end # Usage @@ -239,7 +239,7 @@ def down end # app/models/article.rb -class Article < ActiveRecord::Base +class Article < ApplicationRecord end # Usage @@ -294,7 +294,7 @@ create_table :revisions do |t| end # app/models/revision.rb -class Revision < ActiveRecord::Base +class Revision < ApplicationRecord end # Usage @@ -317,12 +317,12 @@ create_table :comments, id: :uuid, default: 'gen_random_uuid()' do |t| end # app/models/post.rb -class Post < ActiveRecord::Base +class Post < ApplicationRecord has_many :comments end # app/models/comment.rb -class Comment < ActiveRecord::Base +class Comment < ApplicationRecord belongs_to :post end ``` @@ -341,7 +341,7 @@ create_table :users, force: true do |t| end # app/models/device.rb -class User < ActiveRecord::Base +class User < ApplicationRecord end # Usage @@ -370,7 +370,7 @@ create_table(:devices, force: true) do |t| end # app/models/device.rb -class Device < ActiveRecord::Base +class Device < ApplicationRecord end # Usage @@ -410,7 +410,7 @@ create_table :devices, id: :uuid, default: 'gen_random_uuid()' do |t| end # app/models/device.rb -class Device < ActiveRecord::Base +class Device < ApplicationRecord end # Usage @@ -434,7 +434,7 @@ end execute "CREATE INDEX documents_idx ON documents USING gin(to_tsvector('english', title || ' ' || body));" # app/models/document.rb -class Document < ActiveRecord::Base +class Document < ApplicationRecord end # Usage @@ -484,7 +484,7 @@ CREATE VIEW articles AS SQL # app/models/article.rb -class Article < ActiveRecord::Base +class Article < ApplicationRecord self.primary_key = "id" def archive! update_attribute :archived, true diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index ed1c3e7061..4606ac4683 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -25,7 +25,7 @@ Code examples throughout this guide will refer to one or more of the following m TIP: All of the following models use `id` as the primary key, unless specified otherwise. ```ruby -class Client < ActiveRecord::Base +class Client < ApplicationRecord has_one :address has_many :orders has_and_belongs_to_many :roles @@ -33,19 +33,19 @@ end ``` ```ruby -class Address < ActiveRecord::Base +class Address < ApplicationRecord belongs_to :client end ``` ```ruby -class Order < ActiveRecord::Base +class Order < ApplicationRecord belongs_to :client, counter_cache: true end ``` ```ruby -class Role < ActiveRecord::Base +class Role < ApplicationRecord has_and_belongs_to_many :clients end ``` @@ -740,7 +740,7 @@ SELECT "articles".* FROM "articles" WHERE (id > 10) ORDER BY id desc LIMIT 20 The `reorder` method overrides the default scope order. For example: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord has_many :comments, -> { order('posted_at DESC') } end @@ -889,7 +889,7 @@ This behavior can be turned off by setting `ActiveRecord::Base.lock_optimistical To override the name of the `lock_version` column, `ActiveRecord::Base` provides a class attribute called `locking_column`: ```ruby -class Client < ActiveRecord::Base +class Client < ApplicationRecord self.locking_column = :lock_client_column end ``` @@ -970,26 +970,26 @@ Active Record lets you use the names of the [associations](association_basics.ht For example, consider the following `Category`, `Article`, `Comment`, `Guest` and `Tag` models: ```ruby -class Category < ActiveRecord::Base +class Category < ApplicationRecord has_many :articles end -class Article < ActiveRecord::Base +class Article < ApplicationRecord belongs_to :category has_many :comments has_many :tags end -class Comment < ActiveRecord::Base +class Comment < ApplicationRecord belongs_to :article has_one :guest end -class Guest < ActiveRecord::Base +class Guest < ApplicationRecord belongs_to :comment end -class Tag < ActiveRecord::Base +class Tag < ApplicationRecord belongs_to :article end ``` @@ -1199,7 +1199,7 @@ Scoping allows you to specify commonly-used queries which can be referenced as m To define a simple scope, we use the `scope` method inside the class, passing the query that we'd like to run when this scope is called: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord scope :published, -> { where(published: true) } end ``` @@ -1207,7 +1207,7 @@ end This is exactly the same as defining a class method, and which you use is a matter of personal preference: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord def self.published where(published: true) end @@ -1217,7 +1217,7 @@ end Scopes are also chainable within scopes: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord scope :published, -> { where(published: true) } scope :published_and_commented, -> { published.where("comments_count > 0") } end @@ -1241,7 +1241,7 @@ category.articles.published # => [published articles belonging to this category] Your scope can take arguments: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord scope :created_before, ->(time) { where("created_at < ?", time) } end ``` @@ -1255,7 +1255,7 @@ Article.created_before(Time.zone.now) However, this is just duplicating the functionality that would be provided to you by a class method. ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord def self.created_before(time) where("created_at < ?", time) end @@ -1274,7 +1274,7 @@ If we wish for a scope to be applied across all queries to the model we can use `default_scope` method within the model itself. ```ruby -class Client < ActiveRecord::Base +class Client < ApplicationRecord default_scope { where("removed_at IS NULL") } end ``` @@ -1290,7 +1290,7 @@ If you need to do more complex things with a default scope, you can alternativel define it as a class method: ```ruby -class Client < ActiveRecord::Base +class Client < ApplicationRecord def self.default_scope # Should return an ActiveRecord::Relation. end @@ -1301,7 +1301,7 @@ NOTE: The `default_scope` is also applied while creating/building a record. It is not applied while updating a record. E.g.: ```ruby -class Client < ActiveRecord::Base +class Client < ApplicationRecord default_scope { where(active: true) } end @@ -1314,7 +1314,7 @@ Client.unscoped.new # => #<Client id: nil, active: nil> Just like `where` clauses scopes are merged using `AND` conditions. ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord scope :active, -> { where state: 'active' } scope :inactive, -> { where state: 'inactive' } end @@ -1343,7 +1343,7 @@ One important caveat is that `default_scope` will be prepended in `scope` and `where` conditions. ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord default_scope { where state: 'pending' } scope :active, -> { where state: 'active' } scope :inactive, -> { where state: 'inactive' } @@ -1405,7 +1405,7 @@ Enums The `enum` macro maps an integer column to a set of possible values. ```ruby -class Book < ActiveRecord::Base +class Book < ApplicationRecord enum availability: [:available, :unavailable] end ``` @@ -1657,7 +1657,7 @@ a large or often-running query. However, any model method overrides will not be available. For example: ```ruby -class Client < ActiveRecord::Base +class Client < ApplicationRecord def name "I am #{super}" end @@ -1692,7 +1692,7 @@ Person.ids ``` ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord self.primary_key = "person_id" end diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md index ec31385077..dd7adf09a2 100644 --- a/guides/source/active_record_validations.md +++ b/guides/source/active_record_validations.md @@ -20,7 +20,7 @@ Validations Overview Here's an example of a very simple validation: ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true end @@ -80,7 +80,7 @@ method to determine whether an object is already in the database or not. Consider the following simple Active Record class: ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord end ``` @@ -157,7 +157,7 @@ and returns true if no errors were found in the object, and false otherwise. As you saw above: ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true end @@ -175,7 +175,7 @@ even if it's technically invalid, because validations are automatically run only when the object is saved, such as with the `create` or `save` methods. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true end @@ -221,7 +221,7 @@ it doesn't verify the validity of the object as a whole. It only checks to see whether there are errors found on an individual attribute of the object. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true end @@ -239,7 +239,7 @@ To check which validations failed on an invalid attribute, you can use key to get the symbol of the validator: ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true end @@ -285,7 +285,7 @@ the field does exist in your database, the `accept` option must be set to `true` or else the validation will not run. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :terms_of_service, acceptance: true end ``` @@ -297,7 +297,7 @@ It can receive an `:accept` option, which determines the value that will be considered acceptance. It defaults to "1" and can be easily changed. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :terms_of_service, acceptance: { accept: 'yes' } end ``` @@ -309,7 +309,7 @@ and they also need to be validated. When you try to save your object, `valid?` will be called upon each one of the associated objects. ```ruby -class Library < ActiveRecord::Base +class Library < ApplicationRecord has_many :books validates_associated :books end @@ -332,7 +332,7 @@ or a password. This validation creates a virtual attribute whose name is the name of the field that has to be confirmed with "_confirmation" appended. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :email, confirmation: true end ``` @@ -349,7 +349,7 @@ confirmation, make sure to add a presence check for the confirmation attribute (we'll take a look at `presence` later on in this guide): ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :email, confirmation: true validates :email_confirmation, presence: true end @@ -360,7 +360,7 @@ confirmation constraint will be case sensitive or not. This option defaults to true. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :email, confirmation: { case_sensitive: false } end ``` @@ -373,7 +373,7 @@ This helper validates that the attributes' values are not included in a given set. In fact, this set can be any enumerable object. ```ruby -class Account < ActiveRecord::Base +class Account < ApplicationRecord validates :subdomain, exclusion: { in: %w(www us ca jp), message: "%{value} is reserved." } end @@ -393,7 +393,7 @@ This helper validates the attributes' values by testing whether they match a given regular expression, which is specified using the `:with` option. ```ruby -class Product < ActiveRecord::Base +class Product < ApplicationRecord validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/, message: "only allows letters" } end @@ -409,7 +409,7 @@ This helper validates that the attributes' values are included in a given set. In fact, this set can be any enumerable object. ```ruby -class Coffee < ActiveRecord::Base +class Coffee < ApplicationRecord validates :size, inclusion: { in: %w(small medium large), message: "%{value} is not a valid size" } end @@ -428,7 +428,7 @@ This helper validates the length of the attributes' values. It provides a variety of options, so you can specify length constraints in different ways: ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, length: { minimum: 2 } validates :bio, length: { maximum: 500 } validates :password, length: { in: 6..20 } @@ -451,7 +451,7 @@ number corresponding to the length constraint being used. You can still use the `:message` option to specify an error message. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :bio, length: { maximum: 1000, too_long: "%{count} characters is the maximum allowed" } end @@ -483,7 +483,7 @@ WARNING. Note that the regular expression above allows a trailing newline character. ```ruby -class Player < ActiveRecord::Base +class Player < ApplicationRecord validates :points, numericality: true validates :games_played, numericality: { only_integer: true } end @@ -521,7 +521,7 @@ This helper validates that the specified attributes are not empty. It uses the is, a string that is either empty or consists of whitespace. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, :login, :email, presence: true end ``` @@ -531,7 +531,7 @@ whether the associated object itself is present, and not the foreign key used to map the association. ```ruby -class LineItem < ActiveRecord::Base +class LineItem < ApplicationRecord belongs_to :order validates :order, presence: true end @@ -541,7 +541,7 @@ In order to validate associated records whose presence is required, you must specify the `:inverse_of` option for the association: ```ruby -class Order < ActiveRecord::Base +class Order < ApplicationRecord has_many :line_items, inverse_of: :order end ``` @@ -568,7 +568,7 @@ This helper validates that the specified attributes are absent. It uses the is, a string that is either empty or consists of whitespace. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, :login, :email, absence: true end ``` @@ -578,7 +578,7 @@ whether the associated object itself is absent, and not the foreign key used to map the association. ```ruby -class LineItem < ActiveRecord::Base +class LineItem < ApplicationRecord belongs_to :order validates :order, absence: true end @@ -588,7 +588,7 @@ In order to validate associated records whose absence is required, you must specify the `:inverse_of` option for the association: ```ruby -class Order < ActiveRecord::Base +class Order < ApplicationRecord has_many :line_items, inverse_of: :order end ``` @@ -611,7 +611,7 @@ with the same value for a column that you intend to be unique. To avoid that, you must create a unique index on that column in your database. ```ruby -class Account < ActiveRecord::Base +class Account < ApplicationRecord validates :email, uniqueness: true end ``` @@ -623,7 +623,7 @@ There is a `:scope` option that you can use to specify one or more attributes th are used to limit the uniqueness check: ```ruby -class Holiday < ActiveRecord::Base +class Holiday < ApplicationRecord validates :name, uniqueness: { scope: :year, message: "should happen once per year" } end @@ -635,7 +635,7 @@ uniqueness constraint will be case sensitive or not. This option defaults to true. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, uniqueness: { case_sensitive: false } end ``` @@ -658,7 +658,7 @@ class GoodnessValidator < ActiveModel::Validator end end -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates_with GoodnessValidator end ``` @@ -686,7 +686,7 @@ class GoodnessValidator < ActiveModel::Validator end end -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates_with GoodnessValidator, fields: [:first_name, :last_name] end ``` @@ -699,7 +699,7 @@ If your validator is complex enough that you want instance variables, you can easily use a plain old Ruby object instead: ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validate do |person| GoodnessValidator.new(person).validate end @@ -728,7 +728,7 @@ passed to `validates_each` will be tested against it. In the following example, we don't want names and surnames to begin with lower case. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates_each :name, :surname do |record, attr, value| record.errors.add(attr, 'must start with upper case') if value =~ /\A[[:lower:]]/ end @@ -751,7 +751,7 @@ The `:allow_nil` option skips the validation when the value being validated is `nil`. ```ruby -class Coffee < ActiveRecord::Base +class Coffee < ApplicationRecord validates :size, inclusion: { in: %w(small medium large), message: "%{value} is not a valid size" }, allow_nil: true end @@ -764,7 +764,7 @@ will let validation pass if the attribute's value is `blank?`, like `nil` or an empty string for example. ```ruby -class Topic < ActiveRecord::Base +class Topic < ApplicationRecord validates :title, length: { is: 5 }, allow_blank: true end @@ -787,7 +787,7 @@ A `Proc` `:message` value is given two arguments: a message key for i18n, and a hash with `:model`, `:attribute`, and `:value` key-value pairs. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord # Hard-coded message validates :name, presence: { message: "must be given please" } @@ -818,7 +818,7 @@ new record is created or `on: :update` to run the validation only when a record is updated. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord # it will be possible to update email with a duplicated value validates :email, uniqueness: true, on: :create @@ -837,7 +837,7 @@ You can also specify validations to be strict and raise `ActiveModel::StrictValidationFailed` when the object is invalid. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: { strict: true } end @@ -847,7 +847,7 @@ Person.new.valid? # => ActiveModel::StrictValidationFailed: Name can't be blank There is also the ability to pass a custom exception to the `:strict` option. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :token, presence: true, uniqueness: true, strict: TokenGenerationException end @@ -871,7 +871,7 @@ to the name of a method that will get called right before validation happens. This is the most commonly used option. ```ruby -class Order < ActiveRecord::Base +class Order < ApplicationRecord validates :card_number, presence: true, if: :paid_with_card? def paid_with_card? @@ -887,7 +887,7 @@ contain valid Ruby code. You should use this option only when the string represents a really short condition. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :surname, presence: true, if: "name.nil?" end ``` @@ -900,7 +900,7 @@ inline condition instead of a separate method. This option is best suited for one-liners. ```ruby -class Account < ActiveRecord::Base +class Account < ApplicationRecord validates :password, confirmation: true, unless: Proc.new { |a| a.password.blank? } end @@ -912,7 +912,7 @@ Sometimes it is useful to have multiple validations use one condition. It can be easily achieved using `with_options`. ```ruby -class User < ActiveRecord::Base +class User < ApplicationRecord with_options if: :is_admin? do |admin| admin.validates :password, length: { minimum: 10 } admin.validates :email, presence: true @@ -930,7 +930,7 @@ should happen, an `Array` can be used. Moreover, you can apply both `:if` and `:unless` to the same validation. ```ruby -class Computer < ActiveRecord::Base +class Computer < ApplicationRecord validates :mouse, presence: true, if: ["market.retail?", :desktop?], unless: Proc.new { |c| c.trackpad.present? } @@ -984,7 +984,7 @@ class EmailValidator < ActiveModel::EachValidator end end -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :email, presence: true, email: true end ``` @@ -1008,7 +1008,7 @@ so your custom validation methods should add errors to it when you wish validation to fail: ```ruby -class Invoice < ActiveRecord::Base +class Invoice < ApplicationRecord validate :expiration_date_cannot_be_in_the_past, :discount_cannot_be_greater_than_total_value @@ -1032,7 +1032,7 @@ custom validations by giving an `:on` option to the `validate` method, with either: `:create` or `:update`. ```ruby -class Invoice < ActiveRecord::Base +class Invoice < ApplicationRecord validate :active_customer, on: :create def active_customer @@ -1053,7 +1053,7 @@ The following is a list of the most commonly used methods. Please refer to the ` Returns an instance of the class `ActiveModel::Errors` containing all errors. Each key is the attribute name and the value is an array of strings with all errors. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end @@ -1072,7 +1072,7 @@ person.errors.messages # => {} `errors[]` is used when you want to check the error messages for a specific attribute. It returns an array of strings with all error messages for the given attribute, each string with one error message. If there are no errors related to the attribute, it returns an empty array. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end @@ -1097,7 +1097,7 @@ The `add` method lets you add an error message related to a particular attribute The `errors.full_messages` method (or its equivalent, `errors.to_a`) returns the error messages in a user-friendly format, with the capitalized attribute name prepended to each message, as shown in the examples below. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.add(:name, "cannot contain the characters !@#%*()_-+=") end @@ -1115,7 +1115,7 @@ person.errors.full_messages An equivalent to `errors#add` is to use `<<` to append a message to the `errors.messages` array for an attribute: ```ruby - class Person < ActiveRecord::Base + class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.messages[:name] << "cannot contain the characters !@#%*()_-+=" end @@ -1136,7 +1136,7 @@ You can specify a validator type to the returned error details hash using the `errors.add` method. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.add(:name, :invalid_characters) end @@ -1152,7 +1152,7 @@ To improve the error details to contain the unallowed characters set for instanc you can pass additional keys to `errors.add`. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.add(:name, :invalid_characters, not_allowed: "!@#%*()_-+=") end @@ -1172,7 +1172,7 @@ validator type. You can add error messages that are related to the object's state as a whole, instead of being related to a specific attribute. You can use this method when you want to say that the object is invalid, no matter the values of its attributes. Since `errors[:base]` is an array, you can simply add a string to it and it will be used as an error message. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord def a_method_used_for_validation_purposes errors[:base] << "This person is invalid because ..." end @@ -1184,7 +1184,7 @@ end The `clear` method is used when you intentionally want to clear all the messages in the `errors` collection. Of course, calling `errors.clear` upon an invalid object won't actually make it valid: the `errors` collection will now be empty, but the next time you call `valid?` or any method that tries to save this object to the database, the validations will run again. If any of the validations fail, the `errors` collection will be filled again. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end @@ -1207,7 +1207,7 @@ p.errors[:name] The `size` method returns the total number of error messages for the object. ```ruby -class Person < ActiveRecord::Base +class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 181dca4b71..06c5476d45 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -517,17 +517,17 @@ Extensions to `Module` Using plain Ruby you can wrap methods with other methods, that's called _alias chaining_. -For example, let's say you'd like params to be strings in functional tests, as they are in real requests, but still want the convenience of assigning integers and other kind of values. To accomplish that you could wrap `ActionController::TestCase#process` this way in `test/test_helper.rb`: +For example, let's say you'd like params to be strings in functional tests, as they are in real requests, but still want the convenience of assigning integers and other kind of values. To accomplish that you could wrap `ActionDispatch::IntegrationTest#process` this way in `test/test_helper.rb`: ```ruby -ActionController::TestCase.class_eval do +ActionDispatch::IntegrationTest.class_eval do # save a reference to the original process method alias_method :original_process, :process # now redefine process and delegate to original_process - def process(action, params=nil, session=nil, flash=nil, http_method='GET') + def process('GET', path, params: nil, headers: nil, env: nil, xhr: false) params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten] - original_process(action, params, session, flash, http_method) + original_process('GET', path, params: params) end end ``` @@ -537,10 +537,10 @@ That's the method `get`, `post`, etc., delegate the work to. That technique has a risk, it could be the case that `:original_process` was taken. To try to avoid collisions people choose some label that characterizes what the chaining is about: ```ruby -ActionController::TestCase.class_eval do +ActionDispatch::IntegrationTest.class_eval do def process_with_stringified_params(...) params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten] - process_without_stringified_params(action, params, session, flash, http_method) + process_without_stringified_params(method, path, params: params) end alias_method :process_without_stringified_params, :process alias_method :process, :process_with_stringified_params @@ -550,10 +550,10 @@ end The method `alias_method_chain` provides a shortcut for that pattern: ```ruby -ActionController::TestCase.class_eval do +ActionDispatch::IntegrationTest.class_eval do def process_with_stringified_params(...) params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten] - process_without_stringified_params(action, params, session, flash, http_method) + process_without_stringified_params(method, path, params: params) end alias_method_chain :process, :stringified_params end diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md index c272daac28..c3bac320eb 100644 --- a/guides/source/association_basics.md +++ b/guides/source/association_basics.md @@ -101,7 +101,7 @@ NOTE: `belongs_to` associations _must_ use the singular term. If you used the pl The corresponding migration might look like this: ```ruby -class CreateOrders < ActiveRecord::Migration +class CreateOrders < ActiveRecord::Migration[5.0] def change create_table :customers do |t| t.string :name @@ -132,7 +132,7 @@ end The corresponding migration might look like this: ```ruby -class CreateSuppliers < ActiveRecord::Migration +class CreateSuppliers < ActiveRecord::Migration[5.0] def change create_table :suppliers do |t| t.string :name @@ -176,7 +176,7 @@ NOTE: The name of the other model is pluralized when declaring a `has_many` asso The corresponding migration might look like this: ```ruby -class CreateCustomers < ActiveRecord::Migration +class CreateCustomers < ActiveRecord::Migration[5.0] def change create_table :customers do |t| t.string :name @@ -218,7 +218,7 @@ end The corresponding migration might look like this: ```ruby -class CreateAppointments < ActiveRecord::Migration +class CreateAppointments < ActiveRecord::Migration[5.0] def change create_table :physicians do |t| t.string :name @@ -304,7 +304,7 @@ end The corresponding migration might look like this: ```ruby -class CreateAccountHistories < ActiveRecord::Migration +class CreateAccountHistories < ActiveRecord::Migration[5.0] def change create_table :suppliers do |t| t.string :name @@ -345,7 +345,7 @@ end The corresponding migration might look like this: ```ruby -class CreateAssembliesAndParts < ActiveRecord::Migration +class CreateAssembliesAndParts < ActiveRecord::Migration[5.0] def change create_table :assemblies do |t| t.string :name @@ -384,7 +384,7 @@ end The corresponding migration might look like this: ```ruby -class CreateSuppliers < ActiveRecord::Migration +class CreateSuppliers < ActiveRecord::Migration[5.0] def change create_table :suppliers do |t| t.string :name @@ -466,7 +466,7 @@ Similarly, you can retrieve `@product.pictures`. If you have an instance of the `Picture` model, you can get to its parent via `@picture.imageable`. To make this work, you need to declare both a foreign key column and a type column in the model that declares the polymorphic interface: ```ruby -class CreatePictures < ActiveRecord::Migration +class CreatePictures < ActiveRecord::Migration[5.0] def change create_table :pictures do |t| t.string :name @@ -483,7 +483,7 @@ end This migration can be simplified by using the `t.references` form: ```ruby -class CreatePictures < ActiveRecord::Migration +class CreatePictures < ActiveRecord::Migration[5.0] def change create_table :pictures do |t| t.string :name @@ -514,7 +514,7 @@ With this setup, you can retrieve `@employee.subordinates` and `@employee.manage In your migrations/schema, you will add a references column to the model itself. ```ruby -class CreateEmployees < ActiveRecord::Migration +class CreateEmployees < ActiveRecord::Migration[5.0] def change create_table :employees do |t| t.references :manager, index: true @@ -575,7 +575,7 @@ end This declaration needs to be backed up by the proper foreign key declaration on the orders table: ```ruby -class CreateOrders < ActiveRecord::Migration +class CreateOrders < ActiveRecord::Migration[5.0] def change create_table :orders do |t| t.datetime :order_date @@ -611,7 +611,7 @@ end These need to be backed up by a migration to create the `assemblies_parts` table. This table should be created without a primary key: ```ruby -class CreateAssembliesPartsJoinTable < ActiveRecord::Migration +class CreateAssembliesPartsJoinTable < ActiveRecord::Migration[5.0] def change create_table :assemblies_parts, id: false do |t| t.integer :assembly_id @@ -629,7 +629,7 @@ We pass `id: false` to `create_table` because that table does not represent a mo You can also use the method `create_join_table` ```ruby -class CreateAssembliesPartsJoinTable < ActiveRecord::Migration +class CreateAssembliesPartsJoinTable < ActiveRecord::Migration[5.0] def change create_join_table :assemblies, :parts do |t| t.index :assembly_id diff --git a/guides/source/configuring.md b/guides/source/configuring.md index a286a7c5d2..ba2fb4c1cf 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -98,7 +98,7 @@ application. Accepts a valid week day symbol (e.g. `:monday`). * `config.exceptions_app` sets the exceptions application invoked by the ShowException middleware when an exception happens. Defaults to `ActionDispatch::PublicExceptions.new(Rails.public_path)`. -* `config.file_watcher` the class used to detect file updates in the filesystem when `config.reload_classes_only_on_change` is true. Must conform to `ActiveSupport::FileUpdateChecker` API. +* `config.file_watcher` is the class used to detect file updates in the file system when `config.reload_classes_only_on_change` is true. Rails ships with `ActiveSupport::FileUpdateChecker`, the default, and `ActiveSupport::EventedFileUpdateChecker` (this one depends on the [listen](https://github.com/guard/listen) gem). Custom classes must conform to the `ActiveSupport::FileUpdateChecker` API. * `config.filter_parameters` used for filtering out the parameters that you don't want shown in the logs, such as passwords or credit card diff --git a/guides/source/engines.md b/guides/source/engines.md index 359796b1ff..8382bde4d3 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -508,7 +508,7 @@ Turning the model into this: ```ruby module Blorgh - class Article < ActiveRecord::Base + class Article < ApplicationRecord has_many :comments end end @@ -1033,9 +1033,9 @@ typical `GET` to a controller in a controller's functional test like this: ```ruby module Blorgh - class FooControllerTest < ActionController::TestCase + class FooControllerTest < ActionDispatch::IntegrationTest def test_index - get :index + get foos_url ... end end @@ -1049,13 +1049,13 @@ in your setup code: ```ruby module Blorgh - class FooControllerTest < ActionController::TestCase + class FooControllerTest < ActionDispatch::IntegrationTest setup do @routes = Engine.routes end def test_index - get :index + get foos_url ... end end @@ -1129,7 +1129,7 @@ end ```ruby # Blorgh/app/models/article.rb -class Article < ActiveRecord::Base +class Article < ApplicationRecord has_many :comments end ``` @@ -1150,7 +1150,7 @@ end ```ruby # Blorgh/app/models/article.rb -class Article < ActiveRecord::Base +class Article < ApplicationRecord has_many :comments def summary "#{title}" @@ -1171,7 +1171,7 @@ classes at run time allowing you to significantly modularize your code. ```ruby # MyApp/app/models/blorgh/article.rb -class Blorgh::Article < ActiveRecord::Base +class Blorgh::Article < ApplicationRecord include Blorgh::Concerns::Models::Article def time_since_created @@ -1187,7 +1187,7 @@ end ```ruby # Blorgh/app/models/article.rb -class Article < ActiveRecord::Base +class Article < ApplicationRecord include Blorgh::Concerns::Models::Article end ``` diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 5700e71103..1416d00de5 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -679,7 +679,7 @@ If you look in the `db/migrate/YYYYMMDDHHMMSS_create_articles.rb` file (remember, yours will have a slightly different name), here's what you'll find: ```ruby -class CreateArticles < ActiveRecord::Migration +class CreateArticles < ActiveRecord::Migration[5.0] def change create_table :articles do |t| t.string :title @@ -1542,7 +1542,7 @@ In addition to the model, Rails has also made a migration to create the corresponding database table: ```ruby -class CreateComments < ActiveRecord::Migration +class CreateComments < ActiveRecord::Migration[5.0] def change create_table :comments do |t| t.string :commenter diff --git a/guides/source/initialization.md b/guides/source/initialization.md index ebe1cb206a..7bf7eebb62 100644 --- a/guides/source/initialization.md +++ b/guides/source/initialization.md @@ -139,7 +139,8 @@ aliases = { "c" => "console", "s" => "server", "db" => "dbconsole", - "r" => "runner" + "r" => "runner", + "t" => "test" } command = ARGV.shift @@ -158,19 +159,20 @@ defined here to find the matching command. ### `rails/commands/command_tasks.rb` -When one types an incorrect rails command, the `run_command` is responsible for -throwing an error message. If the command is valid, a method of the same name -is called. +When one types a valid Rails command, `run_command!` a method of the same name +is called. If Rails doesn't recognize the command, it tries to run a Rake task +of the same name. ```ruby COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole application runner new version help) def run_command!(command) command = parse_command(command) + if COMMAND_WHITELIST.include?(command) send(command) else - write_error_message(command) + run_rake_task(command) end end ``` diff --git a/guides/source/plugins.md b/guides/source/plugins.md index 922bbb4f73..ae8c30515a 100644 --- a/guides/source/plugins.md +++ b/guides/source/plugins.md @@ -17,7 +17,7 @@ After reading this guide, you will know: This guide describes how to build a test-driven plugin that will: * Extend core Ruby classes like Hash and String. -* Add methods to `ActiveRecord::Base` in the tradition of the `acts_as` plugins. +* Add methods to `ApplicationRecord` in the tradition of the `acts_as` plugins. * Give you information about where to put generators in your plugin. For the purpose of this guide pretend for a moment that you are an avid bird watcher. @@ -182,7 +182,6 @@ To start out, write a failing test that shows the behavior you'd like: require 'test_helper' class ActsAsYaffleTest < ActiveSupport::TestCase - def test_a_hickwalls_yaffle_text_field_should_be_last_squawk assert_equal "last_squawk", Hickwall.yaffle_text_field end @@ -190,7 +189,6 @@ class ActsAsYaffleTest < ActiveSupport::TestCase def test_a_wickwalls_yaffle_text_field_should_be_last_tweet assert_equal "last_tweet", Wickwall.yaffle_text_field end - end ``` @@ -234,22 +232,22 @@ like yaffles. ```ruby # test/dummy/app/models/hickwall.rb -class Hickwall < ActiveRecord::Base +class Hickwall < ApplicationRecord acts_as_yaffle end # test/dummy/app/models/wickwall.rb -class Wickwall < ActiveRecord::Base +class Wickwall < ApplicationRecord acts_as_yaffle yaffle_text_field: :last_tweet end - ``` We will also add code to define the `acts_as_yaffle` method. ```ruby # yaffle/lib/yaffle/acts_as_yaffle.rb + module Yaffle module ActsAsYaffle extend ActiveSupport::Concern @@ -265,7 +263,13 @@ module Yaffle end end -ActiveRecord::Base.include(Yaffle::ActsAsYaffle) +# test/dummy/app/models/application_record.rb + +class ApplicationRecord < ActiveRecord::Base + include Yaffle::ActsAsYaffle + + self.abstract_class = true +end ``` You can then return to the root directory (`cd ../..`) of your plugin and rerun the tests using `rake`. @@ -308,7 +312,13 @@ module Yaffle end end -ActiveRecord::Base.include(Yaffle::ActsAsYaffle) +# test/dummy/app/models/application_record.rb + +class ApplicationRecord < ActiveRecord::Base + include Yaffle::ActsAsYaffle + + self.abstract_class = true +end ``` When you run `rake`, you should see the tests all pass: @@ -329,7 +339,6 @@ To start out, write a failing test that shows the behavior you'd like: require 'test_helper' class ActsAsYaffleTest < ActiveSupport::TestCase - def test_a_hickwalls_yaffle_text_field_should_be_last_squawk assert_equal "last_squawk", Hickwall.yaffle_text_field end @@ -382,7 +391,13 @@ module Yaffle end end -ActiveRecord::Base.include(Yaffle::ActsAsYaffle) +# test/dummy/app/models/application_record.rb + +class ApplicationRecord < ActiveRecord::Base + include Yaffle::ActsAsYaffle + + self.abstract_class = true +end ``` Run `rake` one final time and you should see: diff --git a/guides/source/security.md b/guides/source/security.md index df8c24864e..b301736c36 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -381,9 +381,9 @@ Refer to the Injection section for countermeasures against XSS. It is _recommend **CSRF** Cross-Site Request Forgery (CSRF), also known as Cross-Site Reference Forgery (XSRF), 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/news/item/Symantec-reports-first-active-attack-on-a-DSL-router-735883.html). 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. +A real-world example is a [router reconfiguration by CSRF](http://www.h-online.com/security/news/item/Symantec-reports-first-active-attack-on-a-DSL-router-735883.html). 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 the user, 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 their credentials.
+Another example changed Google Adsense's e-mail address and password. If the victim was logged into Google Adsense, the administration interface for Google advertisement campaigns, an attacker could change the credentials of the victim.
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. diff --git a/guides/source/testing.md b/guides/source/testing.md index 3bfbf4f7ff..58524fd6c5 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -330,7 +330,6 @@ You'll see the usage of some of these assertions in the next chapter. All the basic assertions such as `assert_equal` defined in `Minitest::Assertions` are also available in the classes we use in our own test cases. In fact, Rails provides the following classes for you to inherit from: * `ActiveSupport::TestCase` -* `ActionController::TestCase` * `ActionMailer::TestCase` * `ActionView::TestCase` * `ActionDispatch::IntegrationTest` @@ -682,9 +681,9 @@ Let me take you through one such test, `test_should_get_index` from the file `ar ```ruby # articles_controller_test.rb -class ArticlesControllerTest < ActionController::TestCase +class ArticlesControllerTest < ActionDispatch::IntegrationTest test "should get index" do - get :index + get '/articles' assert_response :success assert_includes @response.body, 'Articles' end @@ -697,7 +696,7 @@ and also ensuring that the right response body has been generated. The `get` method kicks off the web request and populates the results into the response. It accepts 4 arguments: * The action of the controller you are requesting. - This can be in the form of a string or a symbol. + This can be in the form of a string or a route (i.e. `articles_url`). * `params`: option with a hash of request parameters to pass into the action (e.g. query string parameters or article variables). @@ -717,7 +716,7 @@ get(:show, params: { id: 12 }, session: { user_id: 5 }) Another example: Calling the `:view` action, passing an `id` of 12 as the `params`, this time with no session, but with a flash message. ```ruby -get(:view, params: { id: 12 }, flash: { message: 'booya!' }) +get(view_url, params: { id: 12 }, flash: { message: 'booya!' }) ``` NOTE: If you try running `test_should_create_article` test from `articles_controller_test.rb` it will fail on account of the newly added model level validation and rightly so. @@ -727,7 +726,7 @@ Let us modify `test_should_create_article` test in `articles_controller_test.rb` ```ruby test "should create article" do assert_difference('Article.count') do - post :create, params: { article: { title: 'Some title' } } + post '/article', params: { article: { title: 'Some title' } } end assert_redirected_to article_path(Article.last) @@ -758,7 +757,8 @@ To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`, ```ruby test "ajax request" do - get :show, params: { id: articles(:first).id }, xhr: true + article = articles(:first) + get article_url(article), xhr: true assert_equal 'hello world', @response.body assert_equal "text/javascript", @response.content_type @@ -799,11 +799,11 @@ can be set directly on the `@request` instance variable: ```ruby # setting a HTTP Header @request.headers["Accept"] = "text/plain, text/html" -get :index # simulate the request with custom header +get articles_url # simulate the request with custom header # setting a CGI variable @request.headers["HTTP_REFERER"] = "http://example.com/home" -post :create # simulate the request with custom env variable +post article_url # simulate the request with custom env variable ``` ### Testing `flash` notices @@ -818,7 +818,7 @@ Let's start by adding this assertion to our `test_should_create_article` test: ```ruby test "should create article" do assert_difference('Article.count') do - post :create, params: { article: { title: 'Some title' } } + post article_url, params: { article: { title: 'Some title' } } end assert_redirected_to article_path(Article.last) @@ -888,7 +888,7 @@ Let's write a test for the `:show` action: ```ruby test "should show article" do article = articles(:one) - get :show, params: { id: article.id } + get '/article', params: { id: article.id } assert_response :success end ``` @@ -901,7 +901,7 @@ How about deleting an existing Article? test "should destroy article" do article = articles(:one) assert_difference('Article.count', -1) do - delete :destroy, params: { id: article.id } + delete article_url(article) end assert_redirected_to articles_path @@ -913,7 +913,7 @@ We can also add a test for updating an existing Article. ```ruby test "should update article" do article = articles(:one) - patch :update, params: { id: article.id, article: { title: "updated" } } + patch '/article', params: { id: article.id, article: { title: "updated" } } assert_redirected_to article_path(article) end ``` @@ -925,7 +925,7 @@ Our test should now look something like this, disregard the other tests we're le ```ruby require 'test_helper' -class ArticlesControllerTest < ActionController::TestCase +class ArticlesControllerTest < ActionDispatch::IntegrationTest # called before every single test setup do @article = articles(:one) @@ -939,20 +939,20 @@ class ArticlesControllerTest < ActionController::TestCase test "should show article" do # Reuse the @article instance variable from setup - get :show, params: { id: @article.id } + get article_url(@article) assert_response :success end test "should destroy article" do assert_difference('Article.count', -1) do - delete :destroy, params: { id: @article.id } + delete article_url(@article) end assert_redirected_to articles_path end test "should update article" do - patch :update, params: { id: @article.id, article: { title: "updated" } } + patch article_url(@article), params: { article: { title: "updated" } } assert_redirected_to article_path(@article) end end @@ -974,7 +974,7 @@ module SignInHelper end end -class ActionController::TestCase +class ActionDispatch::IntegrationTest include SignInHelper end ``` @@ -982,13 +982,13 @@ end ```ruby require 'test_helper' -class ProfileControllerTest < ActionController::TestCase +class ProfileControllerTest < ActionDispatch::IntegrationTest test "should show profile" do # helper is now reusable from any controller test case sign_in users(:david) - get :show + get profile_url assert_response :success end end @@ -1186,10 +1186,10 @@ Functional testing for mailers involves more than just checking that the email b ```ruby require 'test_helper' -class UserControllerTest < ActionController::TestCase +class UserControllerTest < ActionDispatch::IntegrationTest test "invite friend" do assert_difference 'ActionMailer::Base.deliveries.size', +1 do - post :invite_friend, params: { email: 'friend@example.com' } + post invite_friend_url, params: { email: 'friend@example.com' } end invite_email = ActionMailer::Base.deliveries.last diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index fa6a01671b..9ba5021c4a 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -53,7 +53,7 @@ Don't forget to review the difference, to see if there were any unexpected chang Upgrading from Rails 4.2 to Rails 5.0 ------------------------------------- -### Halting callback chains by returning `false` +### Halting callback chains via `throw(:abort)` In Rails 4.2, when a 'before' callback returns `false` in Active Record and Active Model, then the entire callback chain is halted. In other words, diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md index 1c42ff2914..48fc6bc9c0 100644 --- a/guides/source/working_with_javascript_in_rails.md +++ b/guides/source/working_with_javascript_in_rails.md @@ -81,7 +81,7 @@ Awkward, right? We could pull the function definition out of the click handler, and turn it into CoffeeScript: ```coffeescript -paintIt = (element, backgroundColor, textColor) -> +@paintIt = (element, backgroundColor, textColor) -> element.style.backgroundColor = backgroundColor if textColor? element.style.color = textColor @@ -107,7 +107,7 @@ attribute to our link, and then bind a handler to the click event of every link that has that attribute: ```coffeescript -paintIt = (element, backgroundColor, textColor) -> +@paintIt = (element, backgroundColor, textColor) -> element.style.backgroundColor = backgroundColor if textColor? element.style.color = textColor |