Skip to content

Commit

Permalink
Algumas páginas (#759)
Browse files Browse the repository at this point in the history
  • Loading branch information
HenriqueMorato authored Oct 23, 2022
1 parent 677861c commit abebe6f
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 155 deletions.
45 changes: 27 additions & 18 deletions pt-BR/active_record_migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ class AddUserRefToProducts < ActiveRecord::Migration[7.0]
end
```

Essa migração criará uma coluna `user_id`, [references](#references) é um
Essa migração criará uma coluna `user_id`. [References](#references) é um
abreviação para criar colunas, índices, chaves estrangeiras ou mesmo colunas polimórficas
de associação.

Expand Down Expand Up @@ -332,8 +332,7 @@ end
Que cria uma tabela `products` com uma coluna chamada `name`.

Por padrão, o `create_table` criará uma chave primária chamada `id`. Você pode mudar
o nome da chave primária com a opção `:primary_key` (não esqueça de
atualizar o *model* correspondente) ou, se você não quer uma chave primária, você
o nome da chave primária com a opção `:primary_key` ou, se você não quer uma chave primária, você
pode passar a opção `id: false`. Se você precisa passar opções específicas do banco de dados
você pode colocar um fragmento SQL na opção `:option`. Por exemplo:

Expand Down Expand Up @@ -527,14 +526,22 @@ Embora não seja necessário, você pode adicionar restrições de foreign key (
add_foreign_key :articles, :authors
```

Isso adiciona uma nova *foreign key* (chave estrangeira) à coluna `author_id` da tabela
`articles`. A chave referencia a coluna `id` para a tabela `authors`. Se os
nomes da coluna não puderem ser derivados dos nomes das tabelas, você poderá usar as
opções `:column` e `:primary_key`.
O Rails irá gerar um nome para cada *foreign key* (chave estrangeira) começando com
`fk_rails_` seguido por 10 caracteres que são gerados
especificamente a partir do `from_table` e `column`.
Existe uma opção `:name` para especificar um nome diferente se necessário.
A chamada [`add_foreign_key`][] adiciona uma nova restrição à tabela `articles`.
A restrição garante que existe uma linha na tabela `authors` onde
a coluna `id` corresponde ao `articles.author_id`.

Se o nome da coluna `from_table` não puder ser derivado do nome `to_table`,
você pode usar a opção `:column`. Use a opção `:primary_key` se a
chave primária referenciada não é `:id`.

Por exemplo, para adicionar uma chave estrangeira em `articles.reviewer` referenciando `authors.email`:

```ruby
add_foreign_key :articles, :authors, column: :reviewer, primary_key: :email
```

`add_foreign_key` também suporta opções como `name`, `on_delete`,
`if_not_exists`, `validate` e `deferrable`.

NOTE: O Active Record suporta apenas *foreign keys* (chaves estrangeiras) de coluna única. `execute` e
`structure.sql` são obrigados a usar foreign keys (chaves estrangeiras) compostas. Consulte
Expand All @@ -548,9 +555,6 @@ remove_foreign_key :accounts, :branches

# remove foreign key for a specific column
remove_foreign_key :accounts, column: :owner_id

# remove foreign key by name
remove_foreign_key :accounts, name: :special_fk_name
```

### Quando os Helpers não são Suficientes
Expand Down Expand Up @@ -578,16 +582,17 @@ e

O método `change` é a principal maneira de escrever *migrations*. Funciona para a
maioria dos casos, onde o *Active Record* sabe como reverter a *migration*
automaticamente. Atualmente, o método `change` suporta apenas estas definições de
*migrations*:
automaticamente. Abaixo estão algumas ações que o método `change` suporta:

* [`add_column`][]
* [`add_foreign_key`][]
* [`add_index`][]
* [`add_reference`][]
* [`add_timestamps`][]
* [`change_column_comment`][] (must supply a `:from` and `:to` option)
* [`change_column_default`][] (must supply a `:from` and `:to` option)
* [`change_column_null`][]
* [`change_table_comment`][] (must supply a `:from` and `:to` option)
* [`create_join_table`][]
* [`create_table`][]
* `disable_extension`
Expand Down Expand Up @@ -619,6 +624,8 @@ ou escrever os métodos `up` e `down` em vez de usar o médoto `change`.

[`add_foreign_key`]: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_foreign_key
[`add_timestamps`]: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_timestamps
[`change_column_comment`]: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-change_column_comment
[`change_table_comment`]: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-change_table_comment
[`drop_join_table`]: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-drop_join_table
[`drop_table`]: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-drop_table
[`remove_foreign_key`]: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-remove_foreign_key
Expand Down Expand Up @@ -986,12 +993,12 @@ Arquivos de *schema* também são úteis se você deseja verificar rapidamente q

### Tipos de Schema Dumps

O formato dos arquivos de *schema* gerados pelo Rails é controlado pela configuração `config.active_record.schema_format` em `config/application.rb`. Por padrão, o formato é `:ruby`, mas pode ser também alterado para `:sql`.
O formato dos arquivos de *schema* gerados pelo Rails é controlado pela configuração [`config.active_record.schema_format`][] em `config/application.rb`. Por padrão, o formato é `:ruby`, mas pode ser também alterado para `:sql`.

Se `:ruby` está selecionado, então o arquivo de *schema* é salvo em `db/schema.rb`. Se você analisar este arquivo perceberá que ele se parece muito com uma *migration* gigante.

```ruby
ActiveRecord::Schema.define(version: 2008_09_06_171750) do
ActiveRecord::Schema[7.0].define(version: 2008_09_06_171750) do
create_table "authors", force: true do |t|
t.string "name"
t.datetime "created_at"
Expand All @@ -1016,6 +1023,8 @@ Quando o formato do *schema* é definido como `:sql`, a estrutura do banco de da

Para carregar o *schema* de `db/structure.sql`, execute `bin/rails db:schema:load`. O carregamento deste arquivo é realizado executando os comandos em SQL que ele contém. Por definição, isso irá criar uma cópia perfeita da estrutura do banco de dados.

[`config.active_record.schema_format`]: configuring.html#config-active-record-schema-format

### Schema Dumps e o Controle de Versão

Como os arquivos de *schema* são comumente utilizados para criar novos bancos de dados, é fortemente recomendado que você adicione seu arquivo de *schema* ao controle de versão.
Expand Down
10 changes: 6 additions & 4 deletions pt-BR/active_record_multiple_databases.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ deve compartilhar uma conexão com.

```ruby
class PrimaryApplicationRecord < ActiveRecord::Base
self.primary_abstract_class
self.primary_abstract_class = true
end
```

Expand Down Expand Up @@ -420,7 +420,7 @@ config.active_record.shard_resolver = ->(request) {
In Rails 6.1+, Active Record provides a new internal API for connection management.
In most cases applications will not need to make any changes except to opt-in to the
new behavior (if upgrading from 6.0 and below) by setting
`config.active_record.legacy_connection_handling = false`. If you have a single database
[`config.active_record.legacy_connection_handling`][] to `false`. If you have a single database
application, no other changes will be required. If you have a multiple database application
the following changes are required if your application is using these methods:

Expand All @@ -438,11 +438,13 @@ you'll want writing or reading pools with `connection_handler.connection_pool_li
* If you turn off `legacy_connection_handling` in your application, any method that's unsupported
will raise an error (i.e. `connection_handlers=`).

[`config.active_record.legacy_connection_handling`]: configuring.html#config-active-record-legacy-connection-handling

## Alternando Conexão de Banco de Dados Granular

No Rails 6.1 é possível alternar conexões para um banco de dados ao invés de
todos os bancos de dados globalmente. Para usar este recurso, você deve primeiro definir
`config.active_record.legacy_connection_handling` para` false` nas configurações da sua
[`config.active_record.legacy_connection_handling`][] para` false` nas configurações da sua
aplicação. A maioria das aplicações não precisam fazer nenhuma outra
alteração, uma vez que as APIs públicas têm o mesmo comportamento. Consulte a seção acima para
como habilitar e migrar do `legacy_connection_handling`.
Expand Down Expand Up @@ -548,4 +550,4 @@ Se você quiser carregar um *cache* de *schema* para cada banco de dados, você
Rails also doesn't support automatic load balancing of replicas. This is very
dependent on your infrastructure. We may implement basic, primitive load balancing
in the future, but for an application at scale this should be something your application
handles outside of Rails.
handles outside of Rails.
37 changes: 27 additions & 10 deletions pt-BR/active_record_postgresql.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ NOTE: Você precisa habilitar a extensão `hstore` para usar o hstore.

```ruby
# db/migrate/20131009135255_create_profiles.rb
ActiveRecord::Schema.define do
class CreateProfiles < ActiveRecord::Migration[7.0]
enable_extension 'hstore' unless extension_enabled?('hstore')
create_table :profiles do |t|
t.hstore 'settings'
Expand Down Expand Up @@ -245,20 +245,20 @@ irb> contact.save!

* [definição de tipo](https://www.postgresql.org/docs/current/static/datatype-enum.html)

Atualmente, não existe suporte especial para tipos enumerados. Eles são mapeados como colunas de texto normais:
O tipo pode ser mapeado como uma coluna de texto normal ou para um [`ActiveRecord::Enum`](https://api.rubyonrails.org/classes/ActiveRecord/Enum.html).

```ruby
# db/migrate/20131220144913_create_articles.rb
def up
execute <<-SQL
CREATE TYPE article_status AS ENUM ('draft', 'published');
SQL
create_enum :article_status, ["draft", "published"]

create_table :articles do |t|
t.column :status, :article_status
t.enum :status, enum_type: :article_status, default: "draft", null: false
end
end

# NOTE: It's important to drop table before dropping enum.
# There's no built in support for dropping enums, but you can do it manually.
# You should first drop any table that depends on them.
def down
drop_table :articles

Expand All @@ -271,17 +271,21 @@ end
```ruby
# app/models/article.rb
class Article < ApplicationRecord
enum status: {
draft: "draft", published: "published"
}, _prefix: true
end
```

```irb
irb> Article.create status: "draft"
irb> article = Article.first
irb> article.status_draft!
irb> article.status
=> "draft"
irb> article.status = "published"
irb> article.save!
irb> article.status_published?
=> false
```

Para adicionar um novo valor antes ou depois de um já existente, é necessário usar o [ALTER TYPE](https://www.postgresql.org/docs/current/static/sql-altertype.html):
Expand Down Expand Up @@ -394,7 +398,7 @@ irb> user.settings
=> "01010011"
irb> user.settings = "0xAF"
irb> user.settings
=> 10101111
=> "10101111"
irb> user.save!
```

Expand Down Expand Up @@ -628,3 +632,16 @@ irb> Article.count

NOTE: Esta aplicação só se importa com `Articles` não arquivados. Uma visão também
permite condições para que possamos excluir os `Articles` arquivados diretamente.

Structure dumps
--------------

If your `config.active_record.schema_format` is `:sql`, Rails will call `pg_dump` to generate a
structure dump.

You can use `ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags` to configure `pg_dump`.
For example, to exclude comments from your structure dump, add this to an initializer:

```ruby
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-comments']
```
62 changes: 46 additions & 16 deletions pt-BR/active_record_querying.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,14 +439,13 @@ end

contanto que ele não tenha nenhuma ordenação, pois o método necessita forçar uma ordem interna para iterar.

Se houver uma ordem presente no receptor, o comportamento depende da *flag* `config.active_record.error_on_ignored_order`.
Se houver uma ordem presente no receptor, o comportamento depende da *flag* [`config.active_record.error_on_ignored_order`][].
Se verdadeiro, `ArgumentError` é disparada, caso contrário a ordem será ignorada e um aviso gerado, que é o padrão. Isto pode
ser substituído com a opção `:error_on_ignore`, explicado abaixo.

[`config.active_record.error_on_ignored_order`]: configuring.html#config-active-record-error-on-ignored-order
[`find_each`]: https://api.rubyonrails.org/classes/ActiveRecord/Batches.html#method-i-find_each

##### Options for `find_each`

##### Opções para `find_each`

**`:batch_size`**
Expand Down Expand Up @@ -615,6 +614,25 @@ Book.where("created_at >= :start_date AND created_at <= :end_date",

Isso torna a legibilidade mais clara se você tem um grande número de condições variáveis.

#### Condições que usam `LIKE`

Embora os argumentos de condição sejam automaticamente escapados para evitar injeção de SQL (*SQL injection*), os curingas SQL `LIKE` (ou seja, `%` e `_`) **não** são escapados. Isso pode causar um comportamento inesperado se um valor não limpo for usado em um argumento. Por exemplo:

```ruby
Book.where("title LIKE ?", params[:title] + "%")
```

No código acima, a intenção é corresponder títulos que começam com uma *string* especificada pelo usuário. No entanto, quaisquer ocorrências de `%` ou `_` em `params[:title]` serão tratadas como curingas, levando a resultados de consulta surpreendentes. Em algumas circunstâncias, isso também pode impedir que o banco de dados use um índice pretendido, levando a uma consulta muito mais lenta.

Para evitar esses problemas, use [`sanitize_sql_like`][] para escapar caracteres curinga na parte relevante do argumento:

```ruby
Book.where("title LIKE ?",
Book.sanitize_sql_like(params[:title]) + "%")
```

[`sanitize_sql_like`]: https://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html#method-i-sanitize_sql_like

### Condições de Hash

*Active Record* também permite que você passe em condições de *hash* o que pode aumentar a legibilidade de suas sintaxes de condições. Com condições de *hash*, você passa em uma *hash* com chaves (*keys*) dos campos que deseja qualificados e os valores (*values*) de como deseja qualificá-los:
Expand Down Expand Up @@ -689,6 +707,18 @@ Em outras palavras, essa consulta pode ser gerada chamando `where` sem nenhum ar
SELECT * FROM customers WHERE (customers.orders_count NOT IN (1,3,5))
```

Se uma consulta tiver uma condição usando *hash* com valores não nulos em uma coluna anulável, os registros que tiverem valores `nil` na coluna anulável não serão retornados. Por exemplo:

```ruby
Customer.create!(nullable_contry: nil)
Customer.where.not(nullable_country: "UK")
=> []
# Mas
Customer.create!(nullable_contry: "UK")
Customer.where.not(nullable_country: nil)
=> [#<Customer id: 2, nullable_contry: "UK">]
```

[`where.not`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods/WhereChain.html#method-i-not

### Condições OR
Expand Down Expand Up @@ -1315,7 +1345,7 @@ Ou, em Português: "retorne todos os livros que tem avaliações de um cliente".
##### Unindo Associações Aninhadas (Níveis Múltiplos)

```ruby
Author.joins(books: [{reviews: { customer: :orders} }, :supplier] )
Author.joins(books: [{ reviews: { customer: :orders } }, :supplier] )
```

Isso produz:
Expand Down Expand Up @@ -1349,7 +1379,7 @@ time_range = (Time.now.midnight - 1.day)..Time.now.midnight
Customer.joins(:orders).where(orders: { created_at: time_range }).distinct
```

Para condições mais avançadas ou para reutilizar um escopo nomeado existente, `Relation#merge` pode ser usado. Primeiro, vamos adicionar um novo escopo nomeado ao modelo `Order`:
Para condições mais avançadas ou para reutilizar um escopo nomeado existente, [`merge`][] pode ser usado. Primeiro, vamos adicionar um novo escopo nomeado ao modelo `Order`:

```ruby
class Order < ApplicationRecord
Expand All @@ -1361,7 +1391,7 @@ class Order < ApplicationRecord
end
```

Agora nós podemos usar `Relation#merge` para juntar o escopo `created_in_time_range`:
Agora nós podemos usar `merge` para juntar o escopo `created_in_time_range`:

```ruby
time_range = (Time.now.midnight - 1.day)..Time.now.midnight
Expand Down Expand Up @@ -1430,10 +1460,10 @@ books.each do |book|
end
```

O código acima executará apenas **2** consultas, em oposição às **11** consultas do caso anterior:
O código acima executará apenas **2** consultas, em oposição às **11** consultas do caso original:

```sql
SELECT `books`* FROM `books` LIMIT 10
SELECT `books`.* FROM `books` LIMIT 10
SELECT `authors`.* FROM `authors`
WHERE `authors`.`book_id` IN (1,2,3,4,5,6,7,8,9,10)
```
Expand Down Expand Up @@ -1494,9 +1524,9 @@ Isso ocorre porque é ambíguo se eles devem aparecer no registro do pai ou do f

### preload

Com `preload`, o Active Record garante que seja carregado usando uma consulta para cada associação especificada.
Com `preload`, o Active Record carrega usando uma consulta para cada associação especificada.

Revisitando o caso em que N + 1 ocorreu usando o método `preload`, poderíamos reescrever `Book.limit(10)` para autores:
Revisitando o problema com consultas N + 1, poderíamos reescrever `Book.limit(10)` usar `preload` para autores:

```ruby
books = Book.preload(:author).limit(10)
Expand All @@ -1506,19 +1536,19 @@ books.each do |book|
end
```

O código acima executará apenas **2** consultas, ao contrário de **11** consultas no caso anterior:
O código acima executará apenas **2** consultas, ao contrário de **11** consultas no caso original:

```sql
SELECT `books`* FROM `books` LIMIT 10
SELECT `books`.* FROM `books` LIMIT 10
SELECT `authors`.* FROM `authors`
WHERE `authors`.`book_id` IN (1,2,3,4,5,6,7,8,9,10)
```

NOTE: O método `preload` usa um *array*, *hash* ou um *hash* aninhado de *array/hash* da mesma forma que o método `includes` para carregar qualquer número de associações com uma única chamada `Model.find`. No entanto, ao contrário do método `includes`, não é possível especificar condições para associações carregadas antecipadamente.
NOTE: O método `preload` usa um *array*, *hash* ou um *hash* aninhado de *array/hash* da mesma forma que o método `includes` para carregar qualquer número de associações com uma única chamada `Model.find`. No entanto, ao contrário do método `includes`, não é possível especificar condições para associações carregadas antecipadamente (`preload`).

### eager_load

Com `eager_load`, o Active Record garante que force o carregamento antecipado usando `LEFT OUTER JOIN` para todas as associações especificadas.
Com `eager_load`, o Active Record garante que force o carregamento antecipado usando `LEFT OUTER JOIN`.

Revisitando o caso em que N + 1 ocorreu usando o método `eager_load`, poderíamos reescrever `Book.limit(10)` para autores:

Expand All @@ -1530,7 +1560,7 @@ books.each do |book|
end
```

O código acima executará apenas **2** consultas, ao contrário de **11** consultas no caso anterior:
O código acima executará apenas **2** consultas, ao contrário de **11** consultas no caso original:

```sql
SELECT DISTINCT `books`.`id` FROM `books` LEFT OUTER JOIN `authors` ON `authors`.`book_id` = `books`.`id` LIMIT 10
Expand Down Expand Up @@ -1795,7 +1825,7 @@ Para cada campo (também conhecido como atributo) que você define na sua tabela

Você pode especificar o ponto de exclamação (`!`) no final de um localizador dinâmico para que ele levante um erro `ActiveRecord::RecordNotFound` caso não seja retornado nenhum registro, por exemplo `Customer.find_by_name!("Ryan")`

Se você deseja localizar por *name* e *locked*, você pode encadear esses localizadores juntos simplesmente digitando "`and`" entre os campos. Por exemplo, `Customer.find_by_first_name_and_locked("Ryan", true)`.
Se você deseja localizar ambos por *first_name* e *orders_count*, você pode encadear esses localizadores juntos simplesmente digitando "`and`" entre os campos. Por exemplo, `Customer.find_by_first_name_and_orders_count("Ryan", 5)`.

Enums
-----
Expand Down
Loading

0 comments on commit abebe6f

Please sign in to comment.