Desenvolvimento com Rails, mongoid, rspec e cucumber
Nesse rápido post irei demonstrar como iniciar o desenvolvimento de uma aplicação com o Rails 2.3.8, utilizando como banco de dados NoSql o Mongodb.
Para conexão com o banco, utilizaremos a gem Mongoid. Também iremos configurar para testes o Rspec e o Cucumber. Considerando a parti daqui que você tem todas as gems citadas anteriormente instaladas no seu ambiente.
Primeiro começaremos criando uma aplicação Rails, nada de novo aqui.
rails app_teste
Com isso iremos gerar toda a estrutura da aplicação. Agora vamos configurar as gems utilizadas, em ‘config/enviroment.rb’, adicionaremos dentro do bloco ‘Rails::Initializer.run’ a gem do mongoid:
Rails::Initializer.run do |config| config.gem 'mongoid' config.time_zone = 'UTC' end
Com a gem do Mongoid, não precisaremos mais do ActiveRecord, para remover de sua aplicação basta adicionar dentro do mesmo bloco que você configurou o a gem, a seguinte linha ‘config.frameworks -= [:active_record]‘. Deixando meu enviroment.rb assim:
Rails::Initializer.run do |config| config.frameworks -= [:active_record] config.gem 'mongoid' config.time_zone = 'UTC' end
Quando utilizavamos o ActiveRecord, por padrão ele procurava um arquivo YAML chamado database.yml no qual continha as informações sobre o meu banco. No caso do mongoid, podemos continuar com esse mesmo arquivo, ou criar outro (no meu caso eu prefiro criar um chamado mongoid.yml).
Abaixo segue o meu arquivo yml:
base: &base
adapter: mongodb
# em tempo de execucao vamos adicionar o "-#{Rails.env}" ao nomo do banco
database: "feedse"
# Se estiver rodando o mongodb em outro host,
#vc deveria autenticar-se
#host: host.mongodb.com
#username: your-username
#password: your-password
# use as proximas linhas para colocar algo especifico a cada ambiente
development:
<<: *base
test:
<<: *base
production:
<<: *base
Feito isso, agora precisamos que nossa aplicação leia esse arquivo e configure nossa conexão com o banco. Para isso, criaremos um arquivo chamado ‘mongo.rb’ (ou qualquer outro nome que você queira) dentro do diretório config/initializers.
mongo.rb
require 'yaml' mongo_config = YAML::load(File.read(File.join(Rails.root, 'config/mongoid.yml')))[Rails.env] Mongoid.configure do |config| config.from_hash(mongo_config) end
Com isso, já temos tudo pronto em relação ao nosso banco.
Criaremos então, um model chamado ‘Content’. Lembrando que como não utilizamos mais o ActiveRecord, nossa classe não deverá herdar ActiveRecord::Base.
Abaixo segue a implementação da nossa classe:
class Content include Mongoid::Document field :title, :type => String validates_presence_of :title validates_uniqueness_of :title end
Para que nossa classe seja persistida em nossa banco, precisamos incluir o include Mongoid::Document. Precisamos também definir os campos que ele vai ter, no nosso caso somente o campo ‘title’. A definição básica dos campos segue a seguinte estrutura ‘field
Utilizando o RSpec
Vamos gerar a estrutura do rspec, como faríamos em qualquer outro projeto Rails.
script/generate rspec
Logo após gerar a estrutura, abra o arquivo spec_helper.rb dentro do diretório spec recém gerado, e dentro do bloco Spec::Runner.configure comente as seguinte linhas:
config.use_transactional_fixtures = true config.use_instantiated_fixtures = false config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
Um dos problemas que enfrentei logo quando comecei a mexer com Rspec junto com MongoDb, foi que o rpspec não limpa o banco de testes após executar os mesmos. Logo isso deverá ser feito na mão, para isso adicionaremos dentro do bloco Spec::Runner.configure em o seguinte código:
config.after(:each) do
Mongoid.database.collections.each do |collection|
unless collection.name =~ /^system\./
collection.remove
end
end
end
Deixando o nosso spec_helper.rb assim:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path(File.join(File.dirname(__FILE__),'..','config','environment'))
require 'spec/autorun'
require 'spec/rails'
# in ./support/ and its subdirectories.
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
Spec::Runner.configure do |config|
#config.use_transactional_fixtures = true
#config.use_instantiated_fixtures = false
#config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
#clean database mongodb after tests
config.after(:each) do
Mongoid.database.collections.each do |collection|
unless collection.name =~ /^system\./
collection.remove
end
end
end
end
Nesse caso o Rspec irá limpar o banco depois de cada teste ‘each’, mas você pode efetuar a limpeza somente depois de todos os testes terem rodado, nesse caso ao invés de ‘:each’ como parâmetro, utilizaremos ‘:suite’, e caso você queira executar alguma coisa antes dos testes, utilize o ‘config.before’, que funciona exatamente da mesma maneira do ‘config.after’, com a diferença de ser executado antes(before) dos testes.
Obs: Se você está utilizando também o cucumber e está com problemas em relação a limpeza do banco após os testes, a solução é simples.
Crie o arquivo ‘clean_mongo.rb’ (ou qualquer outro nome) dentro de features/support e adicione nele o código abaixo:
After do |scenario|
Mongoid.database.collections.each do |collection|
unless collection.name =~ /^system\./
collection.remove
end
end
end
E com isso temos nossos testes funcionando com o mongodb.



Comentários