SlideShare uma empresa Scribd logo
1 de 28
Baixar para ler offline
Utilizando Rails e
PostgreSQL
Algumas Limitações do AR no Rails 2
Uso de funções e constraints no banco é ignorado
Chaves compostas estão fora de questão
Não podemos encadear finds
Não podemos mapear SQLs arbitrários em objetos
Como conviver com o Rails 2
Melhorar o suporte a constraints no banco
gem install sexy_pg_constraints
config.active_record.schema_format = :sql
Ex.:
create_table :books do |t|
t.text :title, :null => false
t.text :isbn, :null => false
t.timestamps
end
constrain :books do |t|
t.title :alphanumeric => true, :length_within => 3..50
t.isbn :unique => true, :blacklist => %w(badbook1 badbook2)
end
Constraints geradas no banco
Indexes:
"books_pkey" PRIMARY KEY, btree (id)
"books_isbn_unique" UNIQUE, btree (isbn)
Check constraints:
"books_isbn_blacklist"
CHECK (isbn <> ALL (ARRAY['badbook1'::text, 'badbook2'::text]))
"books_title_alphanumeric" CHECK (title ~* '^[a-z0-9]+$'::text)
"books_title_length_within"
CHECK (length(title) >= 3 AND length(title) <= 50)
Em último caso...
O comando execute nas migrations é seu amigo :)
Para isso não esqueça de utilizar:
config.active_record.schema_format = :sql
Chaves compostas
http://compositekeys.rubyforge.org/
gem install composite_primary_keys
require 'composite_primary_keys' # environment.rb
Ex.:
require 'composite_primary_keys'
class Book < ActiveRecord::Base
set_primary_keys :id, :isbn
end
Book.find(1, 'isbncode')
Chaves compostas
Também adiciona suporte a FKs compostas
E podemos criar rotas com chaves compostas, como:
/controller/show/123000,ISBN123456
Não podemos encadear finds
Usar named_scopes
Eles podem ser encadeados
Usar conditions:
Book.find(:all, :conditions => " id = 1 OR title ~* 'a' ")
Usar o find_by_sql:
Book.find_by_sql("SELECT * FROM books ... ")
Mapeando SQLs para objetos
Podemos usar o find_by_sql
Solução muito frágil para junções, projeções, uniões,
etc...
Para JOINs temos o :include e o :joins
Book.all(:include => :sales)
SELECT * FROM "books"
SELECT "sales.*" FROM "sales"
WHERE ("sales".book_id IN (1,2,3,4))
ORDER BY created_at asc)
Mapeando SQLs para objetos
Para JOINs temos o :include e o :joins
Book.all(:joins => :sales)
SELECT "books".*
FROM "books"
INNER JOIN "sales"
ON "books".id = "sales".book_id
Mapeando SQLs para objetos
Utilizar visões
Começamos pela migration:
execute "
CREATE OR REPLACE VIEW book_sales AS
SELECT
b.id AS book_id,
s.id as sale_id,
b.title, count(s.*)
FROM
books b JOIN sales s ON s.book_id = b.id"
Mapeando SQLs para objetos
Depois criamos um modelo para a nossa visão:
class BookSale < ActiveRecord::Base
belongs_to :book
belongs_to :sales
end
Extensões para o PG no AR
https://github.com/softa/activerecord-postgres-hstore
Suporte ao tipo HStore do PostgreSQL para dados com
atributos dinâmicos
https://github.com/tenderlove/texticle
Suporte ao mecanismo de FTS
Suporte ao módulo pg_trgm para comparação de
trigramas
https://github.com/funny-falcon/activerecord-postgresql-
arrays
Suporte ao tipo array de inteiros
https://github.com/afair/postgresql-cursor
Uso de cursores no PostgreSQL
Melhorias no Rails 3
O AR 3 agora entende o conceito de relações! (Arel)
Posso aplicar uma operação sobre um objeto que
representa uma relação e o retorno será uma nova relação
Por que migrar para o Rails 3?
Encadeamento de operações
Book.where('id = ?', 0).where("title ~ ? ", 'a')
Inclusive com JOINS
Book.where('books.id = ?', 0).joins(:sales)
Conversão de objeto relação para SQL
Book.where('books.id = ?', 0).joins(:sales).to_sql
Tudo carregado para arrays de forma "lazy"
Para mais info vejam:
http://m.onkey.org/2010/1/22/active-record-query-
interface
Por que migrar para o Rails 3?
Possibilita o uso de ORMs alternativos como o excelente
Sequel:
http://sequel.rubyforge.org/
O Sequel ainda é bem mais completo que o AR 3, um ORM
com a perspectiva de quem entende SQL.
Outra opção interessante é o DataMapper (esse fica para
outra palestra)
Algumas vantagens do Sequel
Permite operações como UNION, INTERSECT e EXCEPT
Suporta CTE (consultas com WITH e WITH RECURSIVE)
Permite mostrar todos os SQLs gerados pelo ORM
Desvantagens do Sequel
Sem suporte de alguns plugins famosos do Rails
Devise
Authlogic
Utilizando o Sequel com o Rails 3
Adicionar ao Gemfile
gem 'sequel-rails'
Executar
bundle install
Utilizando o Sequel com o Rails 3
Modifique o arquivo config/application.rb de
...
require 'rails/all'
...
para
...
#require 'rails/all'
require "action_controller/railtie"
require "sequel-rails/railtie"
require "action_mailer/railtie"
require "rails/test_unit/railtie"
...
Utilizando o Sequel com o Rails 3
Qualquer plugin do rails que utilize diretamente o AR deve
ser trocado por um equivalente para o Sequel
Por exemplo:
Paperclip para sequel é a gem: sequel_paperclip
Diferenças entre Sequel e AR
Nomes de adptadores podem mudar (database.yml)
AR:
adapter: postgresql
Sequel
adapter: postgres
Diferenças entre Sequel e AR
Migration no AR:
create_table :menu_items do |t|
t.text :name, :null => false
t.text :description, :null => false
end
Migration no Sequel
create_table :menu_items do
primary_key :id
Text :name, :null => false
Text :description, :null => false
end
Diferenças entre Sequel e AR
Qual valor é inserido na coluna quando eu não informo
nenhum valor no método create?
AR
NULL
Sequel
DEFAULT
Diferenças entre Sequel e AR
Métodos find*
AR (procura por id)
MenuItem.find 1
Tenho métodos find_by_
Sequel (exige o campo e valor de busca)
MenuItem.find :id => 1
Não tenho métodos find_by
Plugins nativos do Sequel
RcteTree
Modelo de árvore usando RECURSIVE CTEs
UpdatePrimaryKey
Para usar chaves naturais
IdentityMap
Cria uma relação de 1-1 entre objetos e linhas do banco
LazyAttributes
Busca campos para o modelo sob demanda.
Extensões para o PG no Sequel
https://github.com/gucki/sequel_column_type_array
Tipos array de inteiro e de varchar no banco
https://github.com/jeremyevans/sequel_postgresql_triggers
Gatilhos em PL/pgSQL criados de forma transparente
para gerenciar: updated_at, created_at, cache de
contadores e cache de somas
https://github.com/jeremyevans/sequel_pg
Acelera comandos SELECT
Muito Obrigado!
Daniel Weinmann
Email: danielweinmann@gmail.com
Twitter: @danielweinmann
Diogo Biazus
Email: diogob@gmail.com
Twitter: @dbiazus

Mais conteúdo relacionado

Semelhante a Utilizando Rails e PostgreSQL

Estripando o Elefante - (Trabalhando com extensões no PostgreSQL)
Estripando o Elefante - (Trabalhando com extensões no PostgreSQL)Estripando o Elefante - (Trabalhando com extensões no PostgreSQL)
Estripando o Elefante - (Trabalhando com extensões no PostgreSQL)Dickson S. Guedes
 
Grails parte 1 - introdução
Grails   parte 1 - introduçãoGrails   parte 1 - introdução
Grails parte 1 - introduçãoJosino Rodrigues
 
Backbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectadosBackbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectadosHenrique Gogó
 
LINQ - Language Integrated Query
LINQ - Language Integrated QueryLINQ - Language Integrated Query
LINQ - Language Integrated QueryDalton Valadares
 
T@rget Trust - Formação: Administrador e Desenvolvedor PostgreSQL
T@rget Trust - Formação: Administrador e Desenvolvedor PostgreSQLT@rget Trust - Formação: Administrador e Desenvolvedor PostgreSQL
T@rget Trust - Formação: Administrador e Desenvolvedor PostgreSQLTargettrust
 
LambdaDay: Backbone.js
LambdaDay: Backbone.jsLambdaDay: Backbone.js
LambdaDay: Backbone.jsGiovanni Bassi
 
Livropythonmysql 091022073751-phpapp01
Livropythonmysql 091022073751-phpapp01Livropythonmysql 091022073751-phpapp01
Livropythonmysql 091022073751-phpapp01julianabdpaiva
 
Estruturas blade-repeticao
Estruturas blade-repeticaoEstruturas blade-repeticao
Estruturas blade-repeticaoRenato Lucena
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN StackBruno Catão
 
Introducao ao desenvolvimento web com Rails
Introducao ao desenvolvimento web com RailsIntroducao ao desenvolvimento web com Rails
Introducao ao desenvolvimento web com RailsKaton Agência Digital
 
Dito Tech Talk RSpec
Dito Tech Talk RSpecDito Tech Talk RSpec
Dito Tech Talk RSpecguest49d83b2
 
Apresentação Java Web Si Ufc Quixadá
Apresentação Java Web Si Ufc QuixadáApresentação Java Web Si Ufc Quixadá
Apresentação Java Web Si Ufc QuixadáZarathon Maia
 
Um Mundo Java Sem XML
Um Mundo Java Sem XMLUm Mundo Java Sem XML
Um Mundo Java Sem XMLiMasters
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2  ruby-ptWorkshop Ruby on Rails dia 2  ruby-pt
Workshop Ruby on Rails dia 2 ruby-ptPedro Sousa
 

Semelhante a Utilizando Rails e PostgreSQL (20)

Estripando o Elefante - (Trabalhando com extensões no PostgreSQL)
Estripando o Elefante - (Trabalhando com extensões no PostgreSQL)Estripando o Elefante - (Trabalhando com extensões no PostgreSQL)
Estripando o Elefante - (Trabalhando com extensões no PostgreSQL)
 
Grails parte 1 - introdução
Grails   parte 1 - introduçãoGrails   parte 1 - introdução
Grails parte 1 - introdução
 
Backbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectadosBackbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectados
 
LINQ - Language Integrated Query
LINQ - Language Integrated QueryLINQ - Language Integrated Query
LINQ - Language Integrated Query
 
T@rget Trust - Formação: Administrador e Desenvolvedor PostgreSQL
T@rget Trust - Formação: Administrador e Desenvolvedor PostgreSQLT@rget Trust - Formação: Administrador e Desenvolvedor PostgreSQL
T@rget Trust - Formação: Administrador e Desenvolvedor PostgreSQL
 
LambdaDay: Backbone.js
LambdaDay: Backbone.jsLambdaDay: Backbone.js
LambdaDay: Backbone.js
 
Acessando o MySql com o Python
Acessando o MySql com o PythonAcessando o MySql com o Python
Acessando o MySql com o Python
 
Livropythonmysql 091022073751-phpapp01
Livropythonmysql 091022073751-phpapp01Livropythonmysql 091022073751-phpapp01
Livropythonmysql 091022073751-phpapp01
 
Estruturas blade-repeticao
Estruturas blade-repeticaoEstruturas blade-repeticao
Estruturas blade-repeticao
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN Stack
 
Xml pucminas2013
Xml pucminas2013Xml pucminas2013
Xml pucminas2013
 
Curso Ruby
Curso RubyCurso Ruby
Curso Ruby
 
Introducao ao desenvolvimento web com Rails
Introducao ao desenvolvimento web com RailsIntroducao ao desenvolvimento web com Rails
Introducao ao desenvolvimento web com Rails
 
Groovy grails
Groovy grailsGroovy grails
Groovy grails
 
Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3
 
Oficial
OficialOficial
Oficial
 
Dito Tech Talk RSpec
Dito Tech Talk RSpecDito Tech Talk RSpec
Dito Tech Talk RSpec
 
Apresentação Java Web Si Ufc Quixadá
Apresentação Java Web Si Ufc QuixadáApresentação Java Web Si Ufc Quixadá
Apresentação Java Web Si Ufc Quixadá
 
Um Mundo Java Sem XML
Um Mundo Java Sem XMLUm Mundo Java Sem XML
Um Mundo Java Sem XML
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2  ruby-ptWorkshop Ruby on Rails dia 2  ruby-pt
Workshop Ruby on Rails dia 2 ruby-pt
 

Mais de Diogo Biazus

Mais de Diogo Biazus (7)

Hercules
HerculesHercules
Hercules
 
Collectd
CollectdCollectd
Collectd
 
Testes Unitarios Com PostgreSQL
Testes Unitarios Com PostgreSQLTestes Unitarios Com PostgreSQL
Testes Unitarios Com PostgreSQL
 
PostgreSQL Ha
PostgreSQL HaPostgreSQL Ha
PostgreSQL Ha
 
Minicurso PostgreSQL
Minicurso PostgreSQLMinicurso PostgreSQL
Minicurso PostgreSQL
 
Arquivos No Banco
Arquivos No BancoArquivos No Banco
Arquivos No Banco
 
Git
GitGit
Git
 

Utilizando Rails e PostgreSQL

  • 2. Algumas Limitações do AR no Rails 2 Uso de funções e constraints no banco é ignorado Chaves compostas estão fora de questão Não podemos encadear finds Não podemos mapear SQLs arbitrários em objetos
  • 3. Como conviver com o Rails 2 Melhorar o suporte a constraints no banco gem install sexy_pg_constraints config.active_record.schema_format = :sql Ex.: create_table :books do |t| t.text :title, :null => false t.text :isbn, :null => false t.timestamps end constrain :books do |t| t.title :alphanumeric => true, :length_within => 3..50 t.isbn :unique => true, :blacklist => %w(badbook1 badbook2) end
  • 4. Constraints geradas no banco Indexes: "books_pkey" PRIMARY KEY, btree (id) "books_isbn_unique" UNIQUE, btree (isbn) Check constraints: "books_isbn_blacklist" CHECK (isbn <> ALL (ARRAY['badbook1'::text, 'badbook2'::text])) "books_title_alphanumeric" CHECK (title ~* '^[a-z0-9]+$'::text) "books_title_length_within" CHECK (length(title) >= 3 AND length(title) <= 50)
  • 5. Em último caso... O comando execute nas migrations é seu amigo :) Para isso não esqueça de utilizar: config.active_record.schema_format = :sql
  • 6. Chaves compostas http://compositekeys.rubyforge.org/ gem install composite_primary_keys require 'composite_primary_keys' # environment.rb Ex.: require 'composite_primary_keys' class Book < ActiveRecord::Base set_primary_keys :id, :isbn end Book.find(1, 'isbncode')
  • 7. Chaves compostas Também adiciona suporte a FKs compostas E podemos criar rotas com chaves compostas, como: /controller/show/123000,ISBN123456
  • 8. Não podemos encadear finds Usar named_scopes Eles podem ser encadeados Usar conditions: Book.find(:all, :conditions => " id = 1 OR title ~* 'a' ") Usar o find_by_sql: Book.find_by_sql("SELECT * FROM books ... ")
  • 9. Mapeando SQLs para objetos Podemos usar o find_by_sql Solução muito frágil para junções, projeções, uniões, etc... Para JOINs temos o :include e o :joins Book.all(:include => :sales) SELECT * FROM "books" SELECT "sales.*" FROM "sales" WHERE ("sales".book_id IN (1,2,3,4)) ORDER BY created_at asc)
  • 10. Mapeando SQLs para objetos Para JOINs temos o :include e o :joins Book.all(:joins => :sales) SELECT "books".* FROM "books" INNER JOIN "sales" ON "books".id = "sales".book_id
  • 11. Mapeando SQLs para objetos Utilizar visões Começamos pela migration: execute " CREATE OR REPLACE VIEW book_sales AS SELECT b.id AS book_id, s.id as sale_id, b.title, count(s.*) FROM books b JOIN sales s ON s.book_id = b.id"
  • 12. Mapeando SQLs para objetos Depois criamos um modelo para a nossa visão: class BookSale < ActiveRecord::Base belongs_to :book belongs_to :sales end
  • 13. Extensões para o PG no AR https://github.com/softa/activerecord-postgres-hstore Suporte ao tipo HStore do PostgreSQL para dados com atributos dinâmicos https://github.com/tenderlove/texticle Suporte ao mecanismo de FTS Suporte ao módulo pg_trgm para comparação de trigramas https://github.com/funny-falcon/activerecord-postgresql- arrays Suporte ao tipo array de inteiros https://github.com/afair/postgresql-cursor Uso de cursores no PostgreSQL
  • 14. Melhorias no Rails 3 O AR 3 agora entende o conceito de relações! (Arel) Posso aplicar uma operação sobre um objeto que representa uma relação e o retorno será uma nova relação
  • 15. Por que migrar para o Rails 3? Encadeamento de operações Book.where('id = ?', 0).where("title ~ ? ", 'a') Inclusive com JOINS Book.where('books.id = ?', 0).joins(:sales) Conversão de objeto relação para SQL Book.where('books.id = ?', 0).joins(:sales).to_sql Tudo carregado para arrays de forma "lazy" Para mais info vejam: http://m.onkey.org/2010/1/22/active-record-query- interface
  • 16. Por que migrar para o Rails 3? Possibilita o uso de ORMs alternativos como o excelente Sequel: http://sequel.rubyforge.org/ O Sequel ainda é bem mais completo que o AR 3, um ORM com a perspectiva de quem entende SQL. Outra opção interessante é o DataMapper (esse fica para outra palestra)
  • 17. Algumas vantagens do Sequel Permite operações como UNION, INTERSECT e EXCEPT Suporta CTE (consultas com WITH e WITH RECURSIVE) Permite mostrar todos os SQLs gerados pelo ORM
  • 18. Desvantagens do Sequel Sem suporte de alguns plugins famosos do Rails Devise Authlogic
  • 19. Utilizando o Sequel com o Rails 3 Adicionar ao Gemfile gem 'sequel-rails' Executar bundle install
  • 20. Utilizando o Sequel com o Rails 3 Modifique o arquivo config/application.rb de ... require 'rails/all' ... para ... #require 'rails/all' require "action_controller/railtie" require "sequel-rails/railtie" require "action_mailer/railtie" require "rails/test_unit/railtie" ...
  • 21. Utilizando o Sequel com o Rails 3 Qualquer plugin do rails que utilize diretamente o AR deve ser trocado por um equivalente para o Sequel Por exemplo: Paperclip para sequel é a gem: sequel_paperclip
  • 22. Diferenças entre Sequel e AR Nomes de adptadores podem mudar (database.yml) AR: adapter: postgresql Sequel adapter: postgres
  • 23. Diferenças entre Sequel e AR Migration no AR: create_table :menu_items do |t| t.text :name, :null => false t.text :description, :null => false end Migration no Sequel create_table :menu_items do primary_key :id Text :name, :null => false Text :description, :null => false end
  • 24. Diferenças entre Sequel e AR Qual valor é inserido na coluna quando eu não informo nenhum valor no método create? AR NULL Sequel DEFAULT
  • 25. Diferenças entre Sequel e AR Métodos find* AR (procura por id) MenuItem.find 1 Tenho métodos find_by_ Sequel (exige o campo e valor de busca) MenuItem.find :id => 1 Não tenho métodos find_by
  • 26. Plugins nativos do Sequel RcteTree Modelo de árvore usando RECURSIVE CTEs UpdatePrimaryKey Para usar chaves naturais IdentityMap Cria uma relação de 1-1 entre objetos e linhas do banco LazyAttributes Busca campos para o modelo sob demanda.
  • 27. Extensões para o PG no Sequel https://github.com/gucki/sequel_column_type_array Tipos array de inteiro e de varchar no banco https://github.com/jeremyevans/sequel_postgresql_triggers Gatilhos em PL/pgSQL criados de forma transparente para gerenciar: updated_at, created_at, cache de contadores e cache de somas https://github.com/jeremyevans/sequel_pg Acelera comandos SELECT
  • 28. Muito Obrigado! Daniel Weinmann Email: danielweinmann@gmail.com Twitter: @danielweinmann Diogo Biazus Email: diogob@gmail.com Twitter: @dbiazus