Rafael Pereira Alonso
Computer Science student at the Federal University of São Carlos - Sorocaba and Ruby On Rails Teacher
# inicialização PITA do BD
DB = SQLite3::Database.new("db/database.sqlite3")
# Inserção de um objeto (em Ruby) no BD
cart = Cart.new(owner: 'Jon Snow')
DB.execute("INSERT INTO 'cart' (owner) VALUES ('#{cart.owner}')")
# Recuperação de um objeto (no BD) para ruby
# 1. pegue as tasks do BD
rows = DB.execute('SELECT * FROM tasks')
# 2. para cada linha recuperada, crie um novo Task. Guarde todos os
# tasks numa array
tasks = rows.map do |row|
# 'done' será 0 ou 1 (no BD). Para transformá-lo em boolean...
row['done'] = !row['done'].zero?
Task.new(row)
end
# BD já configurado (sem ter que inicializar)
# ========== Inserção de um objeto (em Ruby) no BD ===========
cart = Cart.new(owner: 'Jon Snow')
cart.save # => salva no BD e fim
# ======== Recuperação de objetos (no BD) para ruby ==========
# pega todas as linhas do BD, transforma tudo em Task e guarda
# em uma Array
tasks = Task.all
Precisamos configurar umas coisas antes
$ gem install activerecordClonem o repositório abaixo. Algumas configurações já estão prontas (não é preciso se preocupar com as mesmas)
Rake -T
Mostra todos os comandos que o rake pode fazer (com uma pequena desc do que fazem)
Gemfile e Gemfile.lock
Todas as gems que o projeto irá utilizar. As mesmas são 'instaladas' localmente ao rodar '$ bundle install' no terminal
config/application.rb
nosso app.rb!
config/database.yml
YAML é similar ao JSON, exceto pela sintaxe. database.yml guarda as informações sobre o Banco de Dados que iremos utilizar (nesse caso, o tipo do Banco [Sqlite3] e o arquivo do mesmo)
db/migrate/
É onde colocaremos as modificações feitas na estrutura do nosso BD (novas tabelas ou colunas, alteração de nomes/tipos, remoção, etc.)
db/seed.rb
Código para a população inicial do BD
Veremos os dois melhor daqui a pouco!
rake tem uma task para isso!
$ rake db:create # cria o banco de dados no local especificado em db/database.yml
$ rake db:drop # deleta o banco de dados no local especificado em db/database.ymlAlgo mudou na pasta db/
O mundo mágico das migrações
# para criar uma migração, precisamos de um 'timestamp'.
# Felizmente, o rake tem uma task para isso.
$ TS = `rake db:timestamp`
$ touch db/migrate/${TS}_create_tasks.rb
# db/migrate/???????_create_tasks.rb
# estrutura básica de uma migração
# note como o nome da classe bate com o nome do arquivo
class CreateTasks < ActiveRecord::Migration[5.1]
def change
# nosso código aqui
end
endComo criar uma tabela
# db/migrate/???????_create_tasks.rb
# estrutura básica de uma migração
# note como o nome da classe bate com o nome do arquivo
class CreateTasks < ActiveRecord::Migration[5.1]
def change
create_table :tasks do |t|
t.string :desc
t.boolean :done, default: false
t.timestamps # não é obrigatório.
# Guarda quando o objeto foi criado e atualizado
end
end
endPorque a migração ainda não foi executada
# deixe uma task do rake cuidar disso
$ rake db:migrate # roda todas as migrações posteriores à última executada
# db/migrate/???????_add_deadline_to_tasks.rb
# note como o nome da classe bate com o nome do arquivo
class AddDeadlineToTasks < ActiveRecord::Migration[5.1]
def change
add_column :tasks, :deadline, :timestamp, default: Time.now + 2.hours
end
end
# db/migrate/???????_remove_deadline_from_tasks.rb
# note como o nome da classe bate com o nome do arquivo
class RemoveDeadlineFromTasks < ActiveRecord::Migration[5.1]
def change
remove_column :tasks, :deadline
end
end(Contém spoilers de Rails)
class Task
attr_reader :id,:desc,:done
attr_writer :desc
def initialize(args)
@id = args['id']
@desc = args['desc']
@done = args['done']
end
endclass Task < ActiveRecord::Base
endPor meio dele, podemos programar como se estivéssemos no irb, mas com o projeto carregado
$ rake console
task = Task.new
# => #<Task:0x00007feb74ef47c0
# id: nil,
# desc: nil,
# done: false, # nosso default
# created_at: nil,
# updated_at: nil>
task.desc = 'Manjar de AR'
# => #<Task:0x00007feb74ef47c0
# id: nil,
# desc: 'Manjar de AR',
# done: false,
# created_at: nil,
# updated_at: nil>
task.save # Salva o modelo no banco de dados, tabela de mesmo nome do objeto
task
# => #<Task:0x00007feb74ef47c0
# id: 1, gerado pelo BD (NÃO MEXE NISSO)
# desc: 'Manjar de AR',
# done: false,
# created_at: ?????, gerado pelo BD
# updated_at: ?????> gerado pelo BD
# => SELECT * FROM tasks WHERE id = 1;
task = Task.find(1)
task
# => #<Task:???? id: 1, desc: 'Manjar de AR', done: false, ... >
# => SELECT * FROM tasks;
tasks = Task.all
tasks.first
# => #<Task:???? id: 1, desc: 'Manjar de AR', done: false, ... >
# => SELECT desc FROM tasks;
tasks = Task.all.pluck(:desc)
# => SELECT * FROM tasks WHERE done = true;
tasks = Task.where(done: true)
Task.new.saveclass Task < ActiveRecord::Base
valida a presença da descrição
validates :desc, presence: true
end
Task.new.save # => erro
# presence
# uniqueness
# inclusion
# length
# numericalityComo conectar tabelas / modelos
# db/migrate/???????_create_owners.rb
class CreateOwners < ActiveRecord::Migration[5.1]
def change
create_table :tasks do |t|
t.string :nome
t.timestamps
end
end
end
# app/models/owner.rb
class Owner < ActiveRecord::Base
endO task vai referenciar o owner
Uma nova migration
# db/migrate/???????_add_owner_to_tasks.rb
# note como o nome da classe bate com o nome do arquivo
class AddDeadlineToTasks < ActiveRecord::Migration[5.1]
def change
# add_reference, não add_column
add_reference :tasks, :owner, foreing_key: true
end
endBy Rafael Pereira Alonso
Quinta Aula da Atividade Complementar de Ruby On Rails, lecionada na Universidade Federal de São Carlos, campus Sorocaba, no primeiro semestre de 2019
Computer Science student at the Federal University of São Carlos - Sorocaba and Ruby On Rails Teacher