Modelos são importantes.
-- Oficial Alex J. Murphy / RoboCop
O objetivo deste guia é apresentar um conjunto das melhores prescrições de práticas e estilo para desenvolvimento Ruby on Rails 4. Esse é um guia complementar para o já existente liderado pela comunidade Ruby coding style guide.
Alguns dos conselhos aqui são aplicáveis somente no Rails 4.0+.
Você pode gerar um PDF ou uma cópia HTML deste guia usando Pandoc.
Traduções deste guia estão disponíveis nas seguintes linguagens:
Este guia de estilo Rails recomenda boas práticas para que os programadores reais de Rails possam escrever códigos que possam ser mantidos por outros programadores reais de Rails. Um guia de estilos que reflete o uso que o mundo real está acostumado e um guia de estilo que se prende a um ideal que foi rejeitado pelo povo supõe-se que o melhor é não usá-lo para nada - não importa quão bom seja.
O guia é separado em várias seções de regras relacionadas. Eu tentei adicionar a lógica por trás das regras (se estiver omitido, eu assumi que é bastante óbvio).
Eu não vim com todas as regras do nada - são na maioria baseadas na minhas extensa carreira como profissional de engenharia de software, comentários e sugestões de membros da comunidade Rails e vários recursos de programação Rails altamente recomendados.
- Configuração
- Rotas
- Controladores
- Modelos
- Migrações
- Views
- Internacionalização
- Assets
- Mailers
- Extensões de núcleo do Active Support
- Time
- Bundler
- Gerenciamento de processos
-
Coloque código de inicialização customizada em
config/initializers
. O código nessa pasta são executados quando a aplicação inicia. [link] -
Mantenha os códigos de inicialização de cada gem em um arquivo separado com o mesmo nome da gem, por exemplo
carrierwave.rb
,active_admin.rb
, etc. [link] -
Ajuste de acordo com as definições dos ambientes de desenvolvimento, teste e produção (nos arquivos correspondentes dentro de
config/environments/
) [link]-
Marcar assets adicionais para pré-compilação (se houver):
# config/environments/production.rb # Pré-compila assets adicionais (application.js, application.css, # e todo non-JS/CSS já são adicionados) config.assets.precompile += %w( rails_admin/rails_admin.css rails_admin/rails_admin.js )
-
-
Mantenha a configuração que é aplicável à todos ambientes no
config/application.rb
file. [link] -
Crie um ambiente
staging
adicional que se assemelha aoprodução
. [link] -
Mantenha qualquer configuração adicional em arquivos YAML dentro do diretório
config/
. [link]A partir do Rails 4.2, arquivos de configuração YAML podem ser facilmente carregados com o novo método
config_for
:Rails::Application.config_for(:arquivo_yaml)
-
Quando você precisar adicionar mais actions à um resource RESTful (você realmente precisa delas?) use rotas
member
ecollection
. [link]# ruim get 'subscriptions/:id/unsubscribe' resources :subscriptions # bom resources :subscriptions do get 'unsubscribe', on: :member end # ruim get 'photos/search' resources :photos # bom resources :photos do get 'search', on: :collection end
-
Se você precisa definir múltiplas rotas
member/collection
use a alternativa de sintaxe em bloco. [link]resources :subscriptions do member do get 'unsubscribe' # mais rotas end end resources :photos do collection do get 'search' # mais rotas end end
-
Use rotas aninhadas para expressar melhor o relacionamento entre os modelos do ActiveRecord. [link]
class Post < ActiveRecord::Base has_many :comments end class Comments < ActiveRecord::Base belongs_to :post end # routes.rb resources :posts do resources :comments end
-
Se você precisa de rotas aninhadas com mais de 1 nível de profundidade, use a opção
shallow: true
. Isto vai livrar o usuário de longas urls comoposts/1/comments/5/versions/7/edit
e você de longos helpers de url comoedit_post_comment_version
.resources :posts, shallow: true do resources :comments do resources :versions end end
-
Use namespace em rotas para agrupar actions relacionadas. [link]
namespace :admin do # Direciona /admin/products/* ao Admin::ProductsController # (app/controllers/admin/products_controller.rb) resources :products end
-
Nunca use o legado de controlador de rota. Esta rota fará todas actions em todos os controladores serem acessíveis via requisições GET. [link]
# muito ruim match ':controller(/:action(/:id(.:format)))'
-
Não use
match
para definir qualquer rota a não ser que haja necessidade de mapear múltiplos tipos de requisições dentre[:get, :post, :patch, :put, :delete]
para uma única action usando a opção:via
. [link]
-
Mantenha o controlador pequeno - eles devem apenas receber informações da camada de view e não deveria conter qualquer regra de negócio (toda regra de negócio deveria naturalmente ficar dentro do modelo). [link]
-
Cada action do controlador deveria (idealmente) invocar somente um outro método além do inicial
find
ounew
. [link] -
Compartilhar não mais que duas variáveis de instância entre controlador e view. [link]
- Prefira usar render em um template a um inline. [link]
# muito ruim
class ProductsController < ApplicationController
def index
render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>", type: :erb
end
end
# bom
## app/views/products/index.html.erb
<%= render partial: 'product', collection: products %>
## app/views/products/_product.html.erb
<p><%= product.name %></p>
<p><%= product.price %></p>
## app/controllers/foo_controller.rb
class ProductsController < ApplicationController
def index
render :index
end
end
-
Prefira
render plain:
aorender text:
. [link]
# ruim - atribui tipo MIME a um `text/html`
...
render text: 'Ruby!'
...
# ruim - requer declaração explícita do tipo MIME
...
render text: 'Ruby!', content_type: 'text/plain'
...
# bom - curto e preciso
...
render plain: 'Ruby!'
...
- Prefira símbolos correspondentes a um código numérico de status HTTP. Eles são significativos e não parecem números “mágicos” para códigos de status HTTP menos conhecidos. [link]
# ruim
...
render status: 500
...
# bom
...
render status: :forbidden
...
-
Introduza livremente classes de modelos que não usem ActiveRecord. [link]
-
Nomeie modelos com significantes (porém pequenos) nomes sem abreviações. [link]
-
Se você precisa de objetos de modelos que possuam comportamento do ActiveRecord (como validações) sem a funcionalidade do database do ActiveRecord use a gem ActiveAttr. [link]
class Message include ActiveAttr::Model attribute :name attribute :email attribute :content attribute :priority attr_accessible :name, :email, :content validates :name, presence: true validates :email, format: { with: /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}\z/i } validates :content, length: { maximum: 500 } end
Para um exemplo mais completo vejo o RailsCast sobre o assunto.
-
A não ser que tenham alguma importância para o regra de negócio, não ponha métodos no seu modelo que somente formata seus dados (como código gerando HTML). Estes métodos provavelmente só serão chamados na camada de view, então o lugar deles é nos helpers. Mantenhas seus modelos somente para regras de negócios e persistência de dados. [link]
-
Evite alterar os padrões do ActiveRecord (nomes de tabela, chave primária, etc) a não ser que você tenha uma razão muito boa pra isso (como uma base de dados que não está sob seu controle). [link]
# ruim - não faça isso se você pode modificar o schema class Transaction < ActiveRecord::Base self.table_name = 'order' ... end
-
Agrupe métodos estilo macro (
has_many
,validates
, etc) no início da definição da classe. [link]class User < ActiveRecord::Base # mantenha o escopo padrão primeiro (se houver) default_scope { where(active: true) } # contantes entram depois COLORS = %w(red green blue) # logo após, colocamos macros attr relacionados attr_accessor :formatted_date_of_birth attr_accessible :login, :first_name, :last_name, :email, :password # Rails4+ enums depois dos macros attr, prefira sintaxe de hash enum gender: { female: 0, male: 1 } # seguido de associações macros belongs_to :country has_many :authentications, dependent: :destroy # e validações macros validates :email, presence: true validates :username, presence: true validates :username, uniqueness: { case_sensitive: false } validates :username, format: { with: /\A[A-Za-z][A-Za-z0-9._-]{2,19}\z/ } validates :password, format: { with: /\A\S{8,128}\z/, allow_nil: true } # depois nós temos os callbacks before_save :cook before_save :update_username_lower # outras macros (como as do devise) devem ser colocadas depois dos callbacks ... end
-
Prefira
has_many :through
aohas_and_belongs_to_many
. Usarhas_many :through
permite atributos e validações adicionais no modelo. [link]# não tão bom - usando has_and_belongs_to_many class User < ActiveRecord::Base has_and_belongs_to_many :groups end class Group < ActiveRecord::Base has_and_belongs_to_many :users end # forma preferida - usando has_many :through class User < ActiveRecord::Base has_many :memberships has_many :groups, through: :memberships end class Membership < ActiveRecord::Base belongs_to :user belongs_to :group end class Group < ActiveRecord::Base has_many :memberships has_many :users, through: :memberships end
-
Prefira
self[:attribute]
aoread_attribute(:attribute)
. [link]# ruim def amount read_attribute(:amount) * 100 end # bom def amount self[:amount] * 100 end
-
Prefira
self[:attribute] = value
aowrite_attribute(:attribute, value)
. [link]# ruim def amount write_attribute(:amount, 100) end # bom def amount self[:amount] = 100 end
-
Sempre use as novas validações “sexy”. [link]
# ruim validates_presence_of :email validates_length_of :email, maximum: 100 # bom validates :email, presence: true, length: { maximum: 100 }
-
Quando uma validação customizada é usada mais de uma vez ou a validação é o mapeamento de alguma expressão regular, crie um arquivo de validação customizado. [link]
# ruim class Person validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i } end # bom class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors[attribute] << (options[:message] || 'is not a valid email') unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i end end class Person validates :email, email: true end
-
Mantenha validações customizadas dentro de
app/validators
. [link] -
Considere extrair validações customizadas para uma gem compartilhada se você está mantendo várias aplicações relacionadas ou se a validação customizada é genérica o suficiente. [link]
-
Use escopos nomeados livremente. [link]
class User < ActiveRecord::Base scope :active, -> { where(active: true) } scope :inactive, -> { where(active: false) } scope :with_orders, -> { joins(:orders).select('distinct(users.id)') } end
-
Quando um escopo nomeado é definido com um lambda e os parâmetros ficam muito complicados, é preferível fazer um método de classe que sirva ao mesmo propósito do escopo nomeado e retorne um objeto do tipo
ActiveRecord::Relation
. Sem dúvida você pode definir escopos ainda mais simples como este. [link]class User < ActiveRecord::Base def self.with_orders joins(:orders).select('distinct(users.id)') end end
-
Cuidado com o comportamento do método
update_attribute
. Ele não executa as validações de modelo (diferente doupdate_attributes
) e poderia corromper facilmente o estado do modelo. [link] -
Use URLs amigáveis. Mostre algum atributo descritivo do modelo na URL diferente do seu
id
. Existe mais de uma maneira de conseguir isso: [link]-
Sobrescreva o método
to_param
do modelo. Esse método é usado pelo Rails para construir uma URL para o objeto. A implementação padrão retorna oid
do objeto como uma String. Ele pode ser sobrescrito para incluir algum atributo humano-legível.class Person def to_param "#{id} #{name}".parameterize end end
A fim de converter isto para um valor de URL amigável,
parameterize
deve ser chamado na string. Oid
do objeto precisa estar no início para que ele possa ser achado pelo métodofind
do ActiveRecord.-
Use a gem
friendly_id
. Ela permite a criação de URLs humano-legíveis através do uso de algum atributo descritivo do modelo ao invés do seuid
.class Person extend FriendlyId friendly_id :name, use: :slugged end
Veja a documentação da gem para mais informações sobre como usar.
-
-
Use
find_each
para iterar sobre uma coleção de objetos do AR. Fazer um looping através de uma coleção de registros da base de dados (usando o métodoall
, por exemplo) é muito ineficiente já que ele irá tentar instanciar todos os objetos de uma só vez. Nesse caso, métodos de processamento batch te permitem trabalhar com registros em batches, reduzindo significativamente o consumo de memória. [link]# ruim Person.all.each do |person| person.do_awesome_stuff end Person.where('age > 21').each do |person| person.party_all_night! end # bom Person.find_each do |person| person.do_awesome_stuff end Person.where('age > 21').find_each do |person| person.party_all_night! end
-
Desde que o Rails criou callbacks para associações dependentes, sempre chame callbacks
before_destroy
que façam validação comprepend: true
. [link]# ruim (roles sempre serão deletados mesmo que super_admin? seja true) has_many :roles, dependent: :destroy before_destroy :ensure_deletable def ensure_deletable fail "Cannot delete super admin." if super_admin? end # bom has_many :roles, dependent: :destroy before_destroy :ensure_deletable, prepend: true def ensure_deletable fail "Cannot delete super admin." if super_admin? end
-
Defina a opção
dependent
para as associaçõeshas_many
ehas_one
. [link]# ruim class Post < ActiveRecord::Base has_many :comments end # bom class Post < ActiveRecord::Base has_many :comments, dependent: :destroy end
-
Quando persistir objetos AR sempre use o método com o ponto de exclamação ou manipule o valor retornado pelo método. Isso se aplica ao
create
,save
,update
,destroy
,first_or_create
efind_or_create_by
. [link]# ruim user.create(name: 'Bruce') # ruim user.save # bom user.create!(name: 'Bruce') # ou bruce = user.create(name: 'Bruce') if bruce.persisted? ... else ... end # bom user.save! # ou if user.save ... else ... end
-
Evite interpolação de strings em consultas, isso fará seu código suscetível à ataques de SQL injection. [link]
# ruim - parâmetros serão interpolados sem escape Client.where("orders_count = #{params[:orders]}") # bom - parâmetros serão propriamente escapados Client.where('orders_count = ?', params[:orders])
-
Considere usar espaços reservados nomeados ao invés de espaços reservados posicionais quando tiver mais de um espaço reservado na sua consulta. [link]
# até vai.. Client.where( 'created_at >= ? AND created_at <= ?', params[:start_date], params[:end_date] ) # bom Client.where( 'created_at >= :start_date AND created_at <= :end_date', start_date: params[:start_date], end_date: params[:end_date] )
-
Favoreça o uso de
find
aowhere
quando precisar recuperar um único registro pelo id. [link]# ruim User.where(id: id).take # bom User.find(id)
-
Favoreça o uso de
find_by
aowhere
efind_by_attribute
quando você precisar recuperar um único registro por alguns atributos. [link]# ruim User.where(first_name: 'Bruce', last_name: 'Wayne').first # ruim User.find_by_first_name_and_last_name('Bruce', 'Wayne') # bom User.find_by(first_name: 'Bruce', last_name: 'Wayne')
-
Favoreça o uso de
where.not
ao SQL. [link]# ruim User.where("id != ?", id) # bom User.where.not(id: id)
-
Quando especificar uma consulta explícita em um método tal como
find_by_sql
, use heredocs comsquish
. Isso permite formatar legivelmente o SQL com quebra de linhas e indentações, enquanto suporta destaque de sintaxe em muitas ferramentas (incluindo o GitHub, Atom e RubyMine). [link]User.find_by_sql(<<-SQL.squish) SELECT users.id, accounts.plan FROM users INNER JOIN accounts ON accounts.user_id = users.id # further complexities... SQL
String#squish
remove os caracteres de indentação e de nova linha para que o log do servidor mostra uma string de SQL fluida em ve de algo como isso:SELECT\n users.id, accounts.plan\n FROM\n users\n INNER JOIN\n acounts\n ON\n accounts.user_id = users.id
-
Mantenha o
schema.rb
(oustructure.sql
) sob controle de versão. [link] -
Use
rake db:schema:load
em vez derake db:migrate
para inicializar um banco de dados vazio. [link] -
Imponha valores padrões nas próprias migrações em vez de colocar na camada de aplicação. [link]
# ruim - aplicação impõe valor padrão def amount self[:amount] or 0 end
Mesmo a imposição de padrões só no Rails sendo defendida por muitos desenvolvedores Rails, essa é uma abordagem extremamente frágil que deixa seus dados vulneráveis a muitos erros de aplicação. E você terá que considerar o fato de que aplicações não triviais compartilham um banco de dados com outras aplicações, logo impor integridade de dados na aplicação Rails é impossível.
-
Imponha restrições de chave estrangeira. Como do Rails 4.2, ActiveRecord suporta restrições de chave estrangeira nativamente. [link]
-
Ao escrever migrações construtivas (adicionar tabelas ou colunas) use o método
change
ao invés dos métodosup
edown
. [link]# jeito antigo class AddNameToPeople < ActiveRecord::Migration def up add_column :people, :name, :string end def down remove_column :people, :name end end # o jeito novo class AddNameToPeople < ActiveRecord::Migration def change add_column :people, :name, :string end end
-
Não use classes modelo em migrações. As classes modelos estão constantemente evoluindo e, em algum ponto no futuro, as migrações que costumavam funcionar podem parar por causa das mudanças no modelo usado. [link]
-
Nomeie sua chave estrangeira explicitamente em vez de confiar nos nomes de chave estrangeira automaticamente gerados pelo Rails. (http://edgeguides.rubyonrails.org/active_record_migrations.html#foreign-keys)
# ruim class AddFkArticlesToAuthors < ActiveRecord::Migration def change add_foreign_key :articles, :authors end end # bom class AddFkArticlesToAuthors < ActiveRecord::Migration def change add_foreign_key :articles, :authors, name: :articles_author_id_fk end end
[link]
-
Nunca chame a camada de modelo diretamente da view. [link]
-
Nunca faça formatação complexa em views, exporte a formatação para um método no helper ou no modelo. [link]
-
Reduza a duplicação de código através do uso de partials e layouts. [link]
-
Nenhuma string ou outra configuração local específica deveria ser usada nas views, modelos e controladores. Esses textos deveriam ser movidos para os arquivos de localidade no diretório
config/locales
. [link] -
Quando as labels de um modelo do ActiveRecord precisarem ser traduzidas, use o escopo
activerecord
: [link]en: activerecord: models: user: Member attributes: user: name: 'Full name'
Logo
User.model_name.human
irá retornar "Member" eUser.human_attribute_name("name")
irá retornar "Full name". Essas traduções de atributos serão usadas como labels nas views. -
Separe os textos usados nas views das traduções de atributos do ActiveRecord. Coloque os arquivos de localidade para modelos na pasta
locales/models
e os textos usados nas views na pastalocales/views
. [link]-
Quando a organização dos arquivos de localidade estiverem prontos com os diretórios adicionais, estes diretórios devem ser descritos no arquivo
application.rb
em ordem de carregamento.# config/application.rb config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
-
-
Coloque as opções de localização compartilhada, tal como datas e formatos de moedas, em arquivos sob a raiz do diretório
locales
. [link] -
Use o formato curto dos métodos do I18n:
I18n.t
em vez deI18n.translate
eI18n.l
em vez deI18n.localize
. [link] -
Use pesquisa ”preguiçosa” para os textos nas views. Digamos que temos a seguinte estrutura: [link]
en: users: show: title: 'User details page'
O valor de
users.show.title
pode ser pesquisado no templateapp/views/users/show.html.haml
dessa forma:= t '.title'
-
Use as chaves separadas por ponto nos controladores e nos modelos ao invés de especificar a opção
:scope
. As chamadas separadas por ponto são mais fáceis de ler e traçar sua hierarquia. [link]# ruim I18n.t :record_invalid, scope: [:activerecord, :errors, :messages] # bom I18n.t 'activerecord.errors.messages.record_invalid'
-
Informações mais detalhadas sobre o Rails I18n podem ser encontradas no Rails Guides [link]
Use o assets pipeline para aumentar a organização dentro da sua aplicação.
-
Reserve
app/assets
para stylesheets, javascripts, ou imagens customizadas. [link] -
Use
lib/assets
para suas próprias bibliotecas que realmente não se encaixam no escopo da aplicação. [link] -
Código de terceiros como jQuery ou bootstrap devem ser colocados em
vendor/assets
. [link] -
Quando possível, use versões de assets em gem (ex. jquery-rails, jquery-ui-rails, bootstrap-sass, zurb-foundation). [link]
-
Nomeie os mailers como
AlgumaCoisaMailer
. Sem o sufixo Mailer não fica claro qual é o Mailer e a quais views ele está relacionado. [link] -
Providencie ambos templates de view em HTML texto plano. [link]
-
Habilite elevação de erros ao tentar enviar email no ambiente de desenvolvimento. Os erros são desabilitados por padrão. [link]
# config/environments/development.rb config.action_mailer.raise_delivery_errors = true
-
Use um servidor SMTP local como o Mailcatcher no ambiente de desenvolvimento. [link]
# config/environments/development.rb config.action_mailer.smtp_settings = { address: 'localhost', port: 1025, # mais configurações }
-
Providencie configurações padrões para o nome do host. [link]
# config/environments/development.rb config.action_mailer.default_url_options = { host: "#{local_ip}:3000" } # config/environments/production.rb config.action_mailer.default_url_options = { host: 'seu_site.com' } # na sua classe mailer default_url_options[:host] = 'seu_site.com'
-
Se você precisa usar um link para o seu site no email, sempre use o
_url
, e não métodos_path
. Os métodos_url
incluem o nome do host e os métodos_path
não. [link]# ruim Você pode encontrar mais informações sobre esse curso <%= link_to 'aqui', curso_path(@curso) %> # bom ocê pode encontrar mais informações sobre esse curso <%= link_to 'aqui', curso_url(@curso) %>
-
Formate os endereços de
from
eto
devidamente. Use o seguinte formato: [link]# na sua classe mailer default from: 'Seu nome <info@seu_site.com>'
-
Tenha certeza que o método de envio de email para seu ambiente de teste está configurado para
test
: [link]# config/environments/test.rb config.action_mailer.delivery_method = :test
-
O método de envio para desenvolvimento e produção devem ser
smtp
: [link]# config/environments/development.rb, config/environments/production.rb config.action_mailer.delivery_method = :smtp
-
Quando enviar emails html todos os estilos devem estar em linha, já que alguns clientes de email têm problemas com estilos externos. Entretanto, isso os faz mais difíceis de manter e leva a uma duplicação de código. Existem duas gems similares que transformam os estilos em os põe em correspondentes tags html: premailer-rails e roadie. [link]
-
Enviar emails enquanto gera resposta para página deveria ser evitado. Isso causa atrasos no carregamento da página e pode dar timeout na requisição se múltiplos emails são enviados. Para superar isso, emails podem ser enviados em um processo em background com a ajuda da gem sidekiq. [link]
-
Prefira o operador de navegação seguro do Ruby 2.3's
&.
em vez deActiveSupport#try!
. [link]
# ruim
obj.try! :fly
# bom
obj&.fly
-
Prefira métodos da Biblioteca Padrão do Ruby ao invés de alias do
ActiveSupport
. [link]
# ruim
'the day'.starts_with? 'th'
'the day'.ends_with? 'ay'
# bom
'the day'.start_with? 'th'
'the day'.end_with? 'ay'
- Prefira a Biblioteca Padrão do Ruby ao invés de extensões incomuns do ActiveSupport. [link]
# ruim
(1..50).to_a.forty_two
1.in? [1, 2]
'day'.in? 'the day'
# bom
(1..50).to_a[41]
[1, 2].include? 1
'the day'.include? 'day'
-
Prefira os operadores de comparação do Ruby ao invés dos
Array#inquiry
,Numeric#inquiry
eString#inquiry
do ActiveSupport. [link]
# ruim - String#inquiry
ruby = 'two'.inquiry
ruby.two?
# bom
ruby = 'two'
ruby == 'two'
# ruim - Array#inquiry
pets = %w(cat dog).inquiry
pets.gopher?
# bom
pets = %w(cat dog)
pets.include? 'cat'
# ruim - Numeric#inquiry
0.positive?
0.negative?
# bom
0 > 0
0 < 0
-
Configure seu timezone devidamente no
application.rb
. [link]config.time_zone = 'Eastern European Time' # opcional - note que ele só pode ser :utc ou :local (o padrão é :utc) config.active_record.default_timezone = :local
-
Não use
Time.parse
. [link]# ruim Time.parse('2015-03-02 19:05:37') # => Irá assumir que a string com a hora que foi passada está no timezone do sistema. # bom Time.zone.parse('2015-03-02 19:05:37') # => Mon, 02 Mar 2015 19:05:37 EET +02:00
-
Não use
Time.now
. [link]# ruim Time.now # => Retorna hora do sistema e ignora sua configuração de timezone. # bom Time.zone.now # => Fri, 12 Mar 2014 22:04:47 EET +02:00 Time.current # mesma coisa só que menor.
-
Ponha as gems que são usadas só em desenvolvimento e teste dentro de um grupo apropriado no Gemfile. [link]
-
Use somente gems estáveis nos seus projetos. Se você está pensando em usar uma gem pouco conhecida, você deveria dar uma revisada cuidadosa no código fonte dela primeiro. [link]
-
Gems específicas de sistemas operacionais irão, por padrão, resultar em constantes mudanças no
Gemfile.lock
para projetos com muitos desenvolvedores usando diferentes sistemas operacionais. Adicione todas a gems específicas do OS X ao grupodarwin
no Gemfile, e todas as gems específicas do Linux ao grupolinux
: [link]# Gemfile group :darwin do gem 'rb-fsevent' gem 'growl' end group :linux do gem 'rb-inotify' end
Para incluir as gems apropriadas nos ambientes corretos, adicione o seguinte ao
config/application.rb
:platform = RUBY_PLATFORM.match(/(linux|darwin)/)[0].to_sym Bundler.require(platform)
-
Não remova o
Gemfile.lock
do controle de versão. Ele não é um tipo de arquivo gerado randomicamente - ele te dá certeza de que todos os membros da sua equipe tenham as mesmas versões de gems quando executarem obundle install
. [link]
Existem alguns recursos excelentes no estilo Rails que você deveria considerar, se você tiver tempo sobrando:
- The Rails 4 Way
- Ruby on Rails Guides
- The RSpec Book
- The Cucumber Book
- Everyday Rails Testing with RSpec
- Rails 4 Test Prescriptions
- Better Specs for RSpec
Nada escrito neste manual está escrito em pedra. O meu desejo é trabalhar em conjunto com todos interessados no estilo de programação Rails, para que por fim assim nós possamos criar um recurso que irá beneficiar a comunidade de Ruby inteira. Sinta-se livre para abrir tickets ou enviar pull requests com melhorias. Desde já agradeço pela sua ajuda!
Você pode também pode ajudar o projeto (e o RuboCop) com contribuições financeiras via gittip.
Isso é fácil! É só seguir as orientações de contribuição.
Esse trabalho está licenciado sob Creative Commons Attribution 3.0 Unported License
Um guia de estilo voltado para a comunidade é de pouca utilidade se a comunidade não sabe sobre sua existência. Tweet sobre o guia, compartilhe com seus amigos e colegas. Todo comentário, sugestão e opinião que tivermos fará o guia só um pouco melhor. E nós queremos ter o melhor guia possível, não é mesmo?
Até mais,
Bozhidar