Tutorial Ruby on Rails – Conceitos – Parte 2
Introdução
Bem vindos de volta à série de tutoriais sobre Ruby on Rails. Continuaremos a ver alguns conceitos básicos de programação em Ruby on Rails.
Começaremos com um conceito simples já visto:
O que são Gems?
Gems são pacotes de código em Ruby que você pode instalar para extender ou adicionar funcionalidades em sua aplicação.
O que são os arquivos Gemfile e Gemfile.lock?
O arquivo Gemfile é aonde você especifica as gems que pretende usar e permite especificar suas versões.
O arquivo Gemfile.lock é onde o Bundler guarda as versões exatas que foram instaladas.Dessa forma, quando um projeto ou biblioteca é instalado em outra máquina, utilizar o comando “bundle install”, o Bundler ira checar o arquivo Gemfile.lock e instalar exatamente as mesmas versões, pois instalar versões diferentes em máquinas diferentes pode causar erros no projeto.
Qual a diferença entre plugins e gems?
Gems são códigos Ruby que são instalados em uma máquina e ficam disponíveis para todas as suas aplicações Ruby, como “rails” e “rake”.
Plugins também são códigos Ruby, mas são instalados apenas na aplicação em que estão inclusas.
Você verá que em Rails na maioria das vezes será feito o uso de gems.
O que é ORM em Rails?
ORM (Object Relational Mapper) é uma técnica de mapeamento de objeto relacional na qual as tabelas do banco de dados são representadas através de classes e os registros de cada tabela são representados como instâncias das classes correspondentes.
O que é ActiveRecord?
Active Record é a implementação de um sistema ORM. Ele permite várias coisas:
- Associações entre objetos.
- Mapeamento automatizado entre tabelas e classes e entre colunas e atributos.
- Validação de dados.
- Callbacks.
- Hierarquias de herança.
- Manipulação direta de dados assim como dos esquemas de objetos.
- Abstração do banco de dados através de adapters.
- Suporte a log.
- Suporte a migrações.
Rapidamente falando, Active Record é o M do padrão de projetos MVC utilizado pelo Ruby on Rails, uma vez que é a camada responsável por representar os dados da aplicação.
Qual a diferença entre classes e módulos em Ruby?
Da forma que Classes se relacionam com objetos, módulos se relacionam com funções.
Módulos fornecem métodos que podem ser utilizados entre múltiplas classes, como bibliotecas (o que se vê em aplicações Ruby).
Módulos, ao contrário de classes, não podem ser instanciado nem herdados.
Como um contrutor é declarado e utilizado em Ruby?
Construtores em Ruby são declarados da seguinte forma:
[code language=”ruby” collapse=”false”]
class Carro
def initialize(marca, modelo)
@marca = marca
@modelo = modelo
end
end
[/code]
Para utilizá-lo, basta utilizar:
[code language=”ruby” collapse=”false”]
c = Carro.new(‘BMW’, ‘X6’)
[/code]
Qual a diferença entre símbolos e strings em Ruby?
Muitos iniciantes em Ruby tem certa dificuldade de ententer a diferença entre Símbolos e Strings, mesmo ambos sendo muito usados na linguagem.
Resumidamente falando, Símbolos são como Strings exceto pelo fato de que os Símbolos são imutáveis. Ou seja, depois que você cria uma String, por exemplo, você pode editá-la, mas você não pode fazer o mesmo depois de criar um Símbolo.
Veja o seguinte exemplo:
[code language=”ruby” collapse=”false”]
puts "hello" << " world"
puts :hello << :" world"
# => hello world
# => *.rb:2: undefined method `<<‘ for :hello:Symbol (NoMethodError)
[/code]
O erro na segunda instrução ocorreu devido à propriedade imutável de um Símbolo.
Performance
O interpretador do Ruby nunca sabe o que uma String vai armazenar em termos de dados. Por isso cada String precisa de seu próprio lugar na memória. Isso já inclui os custos de alocação.
Se você utilizar o seguinte comando no IRB várias vezes, terá sempre resultados diferentes:
[code language=”ruby” collapse=”false”]
puts "hello world".object_id
[/code]
Mas se você utilizar o seguinte comando, o resultado será sempre o mesmo:
[code language=”ruby” collapse=”false”]
puts :"hello world".object_id
[/code]
Isso acontece porque um símbolo é único, então a cada vez que um é chamado verifica-se sua existência em um dicionário de símbolos, caso exista, o mesmo é referenciado, caso contrário o símbolo é criado e armazenado no dicionário.
Outro detalhe importante de performance é a diferença no custo de comparações entre Strings e Símbolos. A comparação de símbolos é tão simples quanto comparar id’s de objetos, uma vez que um determinado texto sempre está na mesma posição de memória.
A comparação de Strings é computacionalmente mais cara, uma vez que cada String possui seu próprio lugar na memória é necessário comparar os dados reais que compõe a String.
Qual a diferença entre as associações “has_one” e “belongs_to”?
A diferença está no local em que a chave estrangeira se localiza.
Conceitualmente falando, se uma classe A tem uma relação “tem um” ou “has_one” com uma classe B então a Classe A é pai da classe B, então a classe B terá um relacionamento “pertence a” ou “belongs_to” com a classe A.
Ambas expressam uma relação de 1 pra 1, diferenciando apenas pelo fato de que a chave estrangeira se localiza na tabela da classe com a relação “belongs_to”.
[code language=”ruby” collapse=”false”]
class A < ActiveRecord::Base
# Eu referencio a qual loja pertenço.
belongs_to :b
end
class B < ActiveRecord::Base
# Um produto me referencia.
has_one :a
end
[/code]