RailsMetrics is a new Rails engine which stores everything that is happening inside your application in the database, so you can profile each request, besides creating charts, statistics and extract useful information.
I’ve been working on it for the last couple months in parallel with ActiveSupport::Notifications, which is the foundation for RailsMetrics, and it was open sourced today by Engine Yard!
It was a challenging project due to its threaded nature and I will share a couple things I learned during the process in this blog later. For now, you can watch the screencast below to see what it does and how to install it:
As said in the video, getting it released is just the first step and now it’s your turn to fork and improve it by providing a better layout, creating new reports, charts, etc!
In case you are interested here are some screenshots that I tweeted earlier: http://twitpic.com/13e7fn/full and http://twitpic.com/13e7h2/full.
The javascript novell
A week ago I asked what people uses to create charts in Rails so I could evaluate what would be the best library to use in RailsMetrics. There were three types of libraries: server side ones, flash and javascript. Since I don’t want to depend on having neither RMagick nor Flash installed on the developer machine, I chose the javascript kind.
After some research I ended up with three libraries: g.raphael, flot and jqplot.
For RailsMetrics, I chose to use g.raphael since I can easily manipulate the objects it creates and it is the one which looks better (at least imho
). However it has poor documentation and the default charts have poor customization options compared to the other two libraries, so you end up tweaking the chart by hand (which was fine in my experience).
I’m waiting for your pull requests, enjoy!
Tags: charts, gems, javascript, metrics, notifications, rails
Posted in English | 18 Comments »
Today we are celebrating Devise‘s birthday. But wait, if you have started watching Devise since the beginning you may be asking: has Devise already completed one year of life? Nope. Today we are completing exactly 4 months since Devise was released at Rails Summit Latin America 2009. And we are very proud and glad to say that we have just reached version 1.0! Yeah! Let’s celebrate and talk a bit about history.
The beginning
We decided to build Devise based on some requirements we had in a project last year. The majority of our projects usually require an admin interface to configure the application with some CRUD information. And in this specific project, we were needing two different roles in the same application, the admin itself with all its powers to manage the application, and the end users that should be signed in to do some stuff inside the application. Usually only one model would be required in this situation, with some “type” column or flag to determine if the user is an admin or not, right? Okay, but we didn’t like this approach that much. So we started looking at some of the possibilities:
- Authlogic: a really great piece of code and functionality, but a bit messy by handling the session in a model. It also only handles the model part.
- Clearance: full stack, Rails Engine, extra modules, everything we needed. However, packaged with a User model and without the ability to customize it.
Okay, we could pick one of these and with a bit of extra work we would achieve our requirements. But would we need to do it every time this situation happens? We said no. It’s not DRY enough. And we like DRY. So Devise was born.
The main objective of the first Devise version was to get up and running the entire sign in process, including password recovery and confirmation stuff. And everything should work with different roles, which mean you could easily plug and play an Admin, User, Account, or whichever role you needed, in your application, without much effort. And we had a deadline: Rails Summit. It took almost 1 month of work before Rails Summit. I still remember the days before the event, we putting a lot of effort to have Devise up and running, and the README being written during the event. So, we were ready there and presenting Devise to the world.
How it works
Devise was born with the intuit of handling different roles without effort, automatically, and it is achieved with Rails Engines. In addition, Devise is build in top of Warden, a great rack authentication framework. It allowed us to be flexible enough and add different strategies, hooks, and modules easily. In short, Devise:
- Is Rack based;
- Is a complete MVC solution based on Rails Engines;
- Allows you to have multiple roles (or models/scopes) signed in at the same time;
- Is based on a modularity concept: use just what you really need.
The road so far
Devise has started with the basic modules needed for that specific application:
- Authenticatable: responsible for signing users in through a basic login form, handling password validation and authentication.
- Confirmable: manages confirming users account.
- Recoverable: handles password recovery.
- Validatable: basic email and password validation.
Okay, everything we needed were there. Everything else was in a wish list, nicely called TODO. And we decided from the beginning to not add features to Devise until us or somebody else really needed them. But people asked, people needed new features. And they were always there to help, to fork and fix a bug, to comment. We started soon to add new features, the first was:
- Rememberable: handles signing users in automatically from cookies.
After people were asking for easier ways to create their migrations, so we introduced a new module with Devise 0.2:
- Migratable: hooks into ActiveRecord migrations to add helper methods for creating Devise colums. So you can do stuff like
t.authenticatable,t.confirmableand so on.
To help people getting up and running faster, we created some generators. Now they are:
script/generate devise_install: create devise initializer file to enable some configs and copy default locale file.script/generate devise MyModel: create a model with setup for Devise, routes and migration.script/generate devise_views: copy all Devise views to your app/views folder, so you can change it as needed.
Devise 0.3 and 0.4 came soon after, with a lot of bug fixes in generators, I18n, initialization, some deprecations and a bunch of code refactored.
Contributions from community were coming more and more. The first big contribution came with the addition of encryptors. Nowadays Devise supports encrypting passwords with SHA1, SHA512, and BCrypt. It has also support for using the same encryptors as Authlogic, Clearance and Restful Authentication, to help you migrating from these solutions.
At this point we thought: okay, that should be enough. It wasn’t. People needed different ORMs, other than ActiveRecord. So we introduced support to MongoMapper and then we were reaching Devise 0.5.
We were receiving a lot of issues with functional tests, so we introduced some test helpers to help people with the sign in/out process in this kind of tests called Devise::TestHelper.
As applications grow, more roles may be needed. So we created the possibility to scope your views for each role/scope in your application. This way your user can have a different sign in view than the admin, for example. Reaching Devise 0.6, a lot of improvements on routes and DataMapper support were added.
We were full of nice ideas to add new features, and our TODO was bigger than we like. So we came up with:
- Timeoutable: verify each request to timeout the user session after a certain period of inactivity, asking for credentials again.
- Trackable: records how many times each user has signed in, last timestamps and ips.
Also the loading process and ORM support received a lot of work before launching Devise 0.7.
For Devise 0.8 we looked at tests for MongoMapper and the code got a great review. Also some work was done to get Devise up and running with latest version of Warden and its new features, such as serializers. We also extracted a new base module from Confirmable:
- Activatable: allow setting up extra activation methods for your models.
We were receiving a lot of feedback from the community, and then we merged a cool new feature:
- Lockable: lock accounts based on a number of invalid sign in attempts.
Following the same pattern from Rails in this commit we moved flash messages to :notice and :alert, and released Devise 0.9. Step by step the 1.0 version was coming.
What is new
Devise 1.0 introduces a lot of cool features. The community seems to be really appreciating Devise, and we’ve received another great contribution:
- Token Authenticatable: validates authenticity of a user while signing in using an authentication token (also known as “single access token”).
In addition, we created the two most requested features for Devise:
- Registerable: handles sign up users through a registration process, and also editing/updating user info and deleting user account.
- HTTP Authenticatable: http basic authentication.
We also added the possibility to use Migratable while editing a table using change_table, among other fixes.
What comes next
We are preparing a new release of Devise fully compatible with Rails 3. It means Devise has now closed its development for new features in Rails 2.x. We are still going to maintain a 1.0 branch in github for bug fixes to keep everything up and running.
In the end
We would like to say thank you to everyone who has helped us achieve 1.0 version and who is using Devise, testing, creating issues, and giving all this feedback.
Also, for those who were at Rails Summit last year, we proposed something: get the biggest number of watchers on github as fast as possible! When we presented Devise, there were 7 watchers, and if I am right we were 4 of them. At the time of this writing we have 762 watchers. Yeah! I think I can take the risk and say we accomplished it. Thanks!
Let’s celebrate Devise 1.0, and look forward to see Devise and Rails 3. Enjoy!
Happy birthday Devise!
Tags: authentication, devise, engine, plugins, rails
Posted in English | 36 Comments »
Hoje estamos comemorando o aniversário do Devise. Mas espere um pouco, se você está seguindo o Devise desde o início pode estar se perguntando: “O Devise já completou um ano de vida?”. Não. Hoje estamos completando exatamente 4 meses desde que o Devise foi lançado no Rails Summit Latin America 2009. E estamos muito orgulhosos e felizes em dizer que alcançamos a versão 1.0! Yeah! Vamos comemorar e falar um pouquinho sobre a história do projeto.
O início
Decidimos criar o Devise com base em alguns requisitos de um projeto que tivemos no ano passado. A grande maioria de nossos projetos normalmente precisam de uma interface de administração para configurar a aplicação e alguma informação com CRUD. E neste projeto em específico, precisávamos de dois papéis diferentes na mesma aplicação: o administrador com todos os poderes para gerenciar a aplicação, e os usuários finais que deveriam estar devidamente logados para executarem algumas coisas na aplicação. Normalmente essa situação requer um modelo, com alguma coluna de “tipo” ou flag para determinar se o usuário é admin ou não, certo? Ok, mas não gostávamos muito deste método. Então começamos a analisar as possibilidades:
- Authlogic: um código ótimo e cheio de funcionalidade, mas um pouco estranho gerenciando a sessão através de um modelo. Além disso, ele gerenciava apenas a parte do modelo.
- Clearance: completo, funciona como Engine do Rails, módulos adicionais, tudo que precisávamos. Entretanto, ele nos obriga a usar o modelo User, sem possibilidade de customizar isto.
Certo, poderíamos escolher um deles e com um pouco de trabalho extra alcançaríamos nossos requisitos. Mas nós precisaríamos fazer isto toda vez que uma situação dessas acontecesse? Nós respondemos não. Não era DRY o suficiente. E nós gostamos de ser DRY. Então nasceu o Devise.
O principal objetivo da primeira versão do Devise era proporcionar o processo de login completo, incluindo recuperação de senha e confirmação de conta. E tudo deveria funcionar com papéis diferentes, o que significa que você poderia facilmente adicionar em sua aplicação um papel de Admin, User, Account, ou qualquer outro que precisasse, sem muito trabalho. Também tínhamos um prazo: o Rails Summit. Levou quase 1 mês de trabalho antes do Rails Summit. Ainda me lembro os dias que antecederam o evento, nós trabalhando quase como loucos para deixar o Devise redondo, e também o README que foi escrito durante o evento. Então, estávamos prontos e apresentando o Devise para o mundo.
Como ele funciona
O Devise nasceu com o intuito de gerenciar papéis diferentes sem esforço, automaticamente, e isso é conseguido através das Engines do Rails. Além disso, o Devise é construído sobre o Warden, um ótimo framework de autenticação para o Rack. Isso nos permitiu ser bastante flexíveis e adicionar estratégias diferentes, hooks, a módulos facilmente. Em resumo, o Devise:
- É baseado no Rack;
- É uma solução MVC completa com base em Rails Engines;
- Permite que você tenha múltiplos papéis (modelos/escopos) logados ao mesmo tempo;
- É totalmente baseado no conceito de modularidade: use somente o que você realmente precisa.
A estrada até agora
Devise foi lançado com os módulos básicos necessários para aquela aplicação específica:
- Authenticatable: responsável por logar usuários atráves de formulários, gerenciando validação de senha e autenticação.
- Confirmable: controla a confirmação de conta de usuários.
- Recoverable: gerencia a recuperação de senhas.
- Validatable: validação básica de email e senha.
Certo, tínhamos tudo que precisávamos até então. O restante estava em uma wishlist, a qual chamamos de TODO. E decidimos desde o princípio não adicionar funcionalidades ao Devise até que nós ou outra pessoa realmente precisasse. Mas as pessoas pediram, as pessoas precisavam de novas funcionalidades. E elas sempre estiveram lá para ajudar, para criar um fork e corrigir um bug, para comentar. Então logo começamos a adicionar novas funcionalidades, a primeira era:
- Rememberable: gerencia o login automático de usuários a partir de cookies.
Depois as pessoas pediram por maneiras mais fáceis de criar as migratios, então introduzimos um novo módulo com o Devise 0.2:
- Migratable: cria hooks nas migrations do ActiveRecord adicionando alguns métodos para criar os campos para o Devise. Assim você pode fazer coisas como
t.authenticatable,t.confirmablee assim por diante.
Para ajudar as pessoas a iniciarem mais rapidamente, criamos então alguns geradores. Atualmente são eles:
script/generate devise_install: cria um arquivo de inicialização para habilitar algumas configurações e também copia o arquivo padrão de locale.script/generate devise MyModel: cria um modelo já configurado para o Devise, adiciona rotas e uma migration.script/generate devise_views: copia todas as views do Devise para seu diretório app/views, permitindo que você altere como achar necessário.
As versões 0.3 e 0.4 do Devise vieram logo em seguida, com vários bugs corrigidos nos geradores, I18n, inicialização, alguns métodos deprecados e uma porção de código refatorado.
As contribuições da comunidade estavam aparecendo cada vez mais. A primeira grande contribuição veio com a adição dos encryptors. Atualmente o Devise suporta a criptografia de senhas com SHA1, SHA512 e Bcrypt. Ele também possui suporte às mesmas rotinas de criptografia do Authlogic, Clearance e Restful Authentication, para auxiliá-lo a migrar dessas soluções.
Neste ponto pensamos: certo, já deve ser o bastante. Não era. As pessoas precisavam de ORMs diferentes do ActiveRecord. Então adicionamos suporte ao MongoMapper e estávamos alcançando o Devise 0.5.
Estávamos recebendo muito feedback sobre problemas com testes funcionais, então construímos o Devise::TestHelper, que contém métodos para auxiliar as pessoas com o processo de sign in/out nestes testes.
Conforme as aplicações crescem, mais papéis podem ser necessários. Então adicionamos a possibilidade de criar views específicas para cada papel/escopo de sua aplicação. Assim seu usuário poderia ter uma view para logar diferente do administrador, por exemplo. Chegando na versão 0.6, várias melhorias foram feitas na geração de rotas e o suporte ao DataMapper foi adicionado.
Estávamos cheio de idéias legais para adicionar novas funcionalidades, e nosso TODO estava maior do que gostamos. Então surgimos com:
- Timeoutable: faz uma checagem em cada request para destruir a sessão do usuário após um certo período de inatividade, pedindo por credenciais novamente.
- Trackable: registra o número de logins do usuário, última data/hora e ip usados para acessar.
Também o processo de carregamento e o suporte a diferentes ORMs receberam uma boa atenção com o lançamento do Devise 0.7.
Para a versão 0.8 do Devise melhoramos os testes para o MongoMapper e fizemos uma grande revisão no código. Algum esforço também foi feito para ter o Devise rodando com a última versão do Warden e as novas features, tais como os serializers. Outro módulo base foi extraído do Confirmable:
- Activatable: permite configurar métodos adicionais para ativação de um modelo.
Com muito feedback vindo da comunidade, fizemos merge de uma nova funcionalidade bacana:
- Lockable: bloqueia contas com base no número de tentativas de login inválidas.
Seguindo o mesmo padrão do Rails neste commit alteramos as mensagens flash para :notice e :alert, e lançamos o Devise 0.9. Passo a passo a versão 1.0 estava chegando.
O que há de novo
O Devise 1.0 traz uma grande variedade de funcionalidades legais. A comunidade parece estar realmente apreciando o Devise, e recebemos outra grande contribuição:
- Token Authenticatable: valida a autenticidade de um usuário atráves do login com um token de autenticação (também conhecido como “token de acesso único”).
Além disso, criamos as duas funcionalidades mais pedidas para o Devise:
- Registerable: controla o registro de usuários (sign up), e também edição/atualização das informações do usuário e cancelamento de conta.
- HTTP Authenticatable: autenticação http basic.
Também adicionamos a possibilidade de usar o Migratable ao editar uma tabela, usando change_table, dentre outras correções.
O que vem agora
Estamos preparando um novo release do Devise totalmente compatível com o Rails 3. Isso significa que a partir de agora o Devise está fechado para desenvolvimento de novas funcionalidades no Rails 2.x. Vamos manter um branch da versão 1.0 no github para correção de bugs mantendo tudo funcionando.
Para terminar
Gostaríamos de dizer muito obrigado a todos que nos ajudaram a chegar a versão 1.0 e a quem está utilizando o Devise, testando, criando issues e nos dando todo este feedback.
Também, para aqueles que estavam no Rails Summit do ano passado, nós propusemos algo: alcançar o maior número de seguidores no github tão rápido quanto possível! Quando apresentamos o Devise, haviam 7 seguidores, e se estou correto nós eramos 4 deles. No momento da redação deste post nós temos 762 seguidores. Yeah! Acho que posso assumir o risco e dizer que nós conseguimos. Obrigado!
Vamos comemorar o Devise 1.0, e aguardar ansiosos para ver o Devise com o Rails 3. Aproveite!
Feliz aniversário Devise!
Posted in Português | Comments Off
So, you already did the right choice of using Delayed Job for your background processing, great! But, how are you going to be certain that your background processing will still be happening while you are sleeping? And if your Delayed Job process goes down, are you going to wake up in the dawn e restart it manually? I wouldn’t do that, I really appreciate my sleep. So, what’s the solution?
As rubyists and railers, we already know there are solutions, like God, that do this job for us. However, there are another solutions, like Bluepill. Bluepill is a process monitoring tool like God, but, unlike God, it doesn’t have memory leak, according to its authors.
Well, as I don’t want to wake up in the dawn to restart my Delayed Job process, and neither I want to restart my God process because of memory leaking, I decided to use Bluepill. But, how I use Bluepill to monitor my Delayed Job process?
In order to configure Bluepill to monitor Delayed Job, and use Capistrano to automate some tasks, we have basically 4 steps:
- Install and configure Delayed Job
- Install and configure Bluepill
- Write a Capistrano Recipe for Bluepill
- Set some stuff in /etc/sudoers
Let’s take a look at each step.
Installing and configuring Delayed Job
Installing and configuring Delayed Job is super simple, just read the project’s README, which is very clear. I also recommend watching the RailsCast episode about Delayed Job, there is some good information there, like using the Delayed Job CollectiveIdea’s fork, instead of the original repo’s version.
Installing and configuring Bluepill
There’s no secret in installing Bluepill too, you just need to read the project’s README and follow its steps.
In the confiuration part, you can see all the options in the README too. In my case, the configuration file is at RAILS_ROOT/config/production.pill.
Bluepill.application("my_app") do |app| app.process("delayed_job") do |process| process.working_dir = "/home/deploy/my_app/current" process.start_grace_time = 10.seconds process.stop_grace_time = 10.seconds process.restart_grace_time = 10.seconds process.start_command = "ruby script/delayed_job -e production start" process.stop_command = "ruby script/delayed_job -e production stop" process.pid_file = "/home/deploy/my_app/shared/pids/delayed_job.pid" process.uid = "deploy" process.gid = "deploy" end end
However, I had a little problem between the interaction of Bluepill and Delayed Job. Delayed Job is not interpreting very well the -e production flag. You can see more details about that in an issue I opened.
The first solution I thought was to use RAILS_ENV=production ruby script/delayed_job start, however, for some reason that I don’t know exactly, it didn’t work.
So, the solution I came up with was to modify the file in RAILS_ROOT/script/delayed_job to the following one:
1 2 3 4 5 6 7 8 9 | #!/usr/bin/env ruby # TODO improve the line of code below # The line below is just a hack while we wait the delayed job guys answer the following issue # http://github.com/collectiveidea/delayed_job/issues#issue/38 ENV['RAILS_ENV'] ||= "production" require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) require 'delayed/command' Delayed::Command.new(ARGV).daemonize |
As the -e production was not being interpreted properly by Delayed Job, I’m setting manually the RAILS_ENV to production (line 6), therefore I’m supposing that you are using Bluepill to monitor processes that are in a production environment.
Capistrano recipe for Bluepill
In order to automate the start and stop Bluepill’s tasks, I wrote the following capistrano’s recipe:
# deploy credentials set :user, "deploy" set :deploy_to, "/home/deploy/#{application}" set :use_sudo, false set :rails_env, "production" # Bluepill related tasks after "deploy:update", "bluepill:quit", "bluepill:start" namespace :bluepill do desc "Stop processes that bluepill is monitoring and quit bluepill" task :quit, :roles => [:app] do sudo "bluepill stop" sudo "bluepill quit" end desc "Load bluepill configuration and start it" task :start, :roles => [:app] do sudo "bluepill load /home/deploy/my_app/current/config/production.pill" end desc "Prints bluepills monitored processes statuses" task :status, :roles => [:app] do sudo "bluepill status" end end
Note that instead of using the run capistrano’s method, I’m using the sudo method. I’m doing this because the bluepill command must be run as root. And that, takes us to the next topic.
/etc/sudoers
Since I need to run the bluepill command as root, should I change from set :user, "deploy" to set :user, "root"? I think it’s not a good idea, we don’t like to give root access to anything, even to deployment. So, what should I do? It’s simple, you just need to edit your sudoers file.
In order to do this, you need to use the visudo command to open and edit the /etc/sudoers file. Once with the file opened, just add the following line to the end of the file:
deploy ALL=(ALL) NOPASSWD: /usr/local/bin/bluepill
Now, you’re done, the deploy user already can do sudo bluepill without giving any password. Problem solved without opening security holes.
After these 4 steps, you’re ready to sleep at night without worrying about your Delayed Job process. And, if you want to know the status of the monitored processes by Buepill, you just need to run the following capistrano task in your local machine:
cap bluepill:status
And you, what are your solutions to sleep in peace?
Update: if are having trouble with restarting Bluepill with Capistrano, take a look at this.
Tags: bluepill, capistrano, delayed job, process monitoring
Posted in English | 12 Comments »
Então você já fez a feliz escolha de tratar seu processamento em background com Delayed Job, ótimo! Mas como ter certeza que esse processamento vai continuar acontecendo enquanto você estiver dormindo? E se o o processo do Delayed Job cair, você vai acordar de madrugada e levantá-lo na mão? Eu não faria isso, gosto do meu sono. Qual a solução então?
Não é nenhuma novidade para nós, rubyistas e railers, que existem soluções como o God para fazerem o trabalho de monitoramento de processos. No entanto, existem outras soluções, como o Bluepill. O Bluepill é uma ferramenta de monitoramento de processos assim como o God, mas diferente dele, não tem memory leak, segundo seus autores.
Bem, como não quero acordar de madrugada para levantar meu processo do Delayed Job na mão, e também não quero ficar restartando um processo do God por causa de memory leak, resolvi usar o Bluepill. Mas como uso o Bluepill para monitorar o Delayed Job?
Para configurar o Bluepill para monitorar o Delayed Job, e usar o Capistrano para automatizar algumas tarefas, temos basicamente 4 passos:
- Instalar e configurar o Delayed job
- Instalar e configurar o Bluepill
- Escrever a receita de capistrano para o Bluepill
- Setar algumas coisas do arquivo /etc/sudoers
Vamos dar uma olhada em detalhes em cada passo.
Instalação e configuração do Delayed Job
Instalar e configurar o Delayed Job é super simples, basta ler o README do projeto, que está bem claro. Recomendo também assistir ao RailsCast sobre o Delayed Job. Foi de lá que tirei a informação de usar o fork do Delayed Job da Collective Idea ao invés da versão do repositório original.
Instalação e configuração do Bluepill
Instalar o Bluepill também não tem muito segredo, basta você ler o README do projeto e seguir os passos que estão descritos lá.
Na parte da configuração, você pode ver as opções também no README do projeto. No meu caso, esse arquivo está em RAILS_ROOT/config/production.pill.
Bluepill.application("my_app") do |app| app.process("delayed_job") do |process| process.working_dir = "/home/deploy/my_app/current" process.start_grace_time = 10.seconds process.stop_grace_time = 10.seconds process.restart_grace_time = 10.seconds process.start_command = "ruby script/delayed_job -e production start" process.stop_command = "ruby script/delayed_job -e production stop" process.pid_file = "/home/deploy/my_app/shared/pids/delayed_job.pid" process.uid = "deploy" process.gid = "deploy" end end
No entanto, eu tive um pequeno problema com a interação do Bluepill e o Delayed Job. Ao passar a flag -e production para o Delayed Job, ele não a estava interpretando direito. Você pode ver mais detalhes sobre isso numa issue que abri no repo do Delayed Job.
A primeira solução que pensei, foi usar RAILS_ENV=production ruby script/delayed_job start, no entanto por algum motivo que ainda desconheço, isso não funcionou.
A solução que cheguei então para resolver esse problema, foi modificar o arquivo que está em RAILS_ROOT/script/delayed_job para o seguinte:
1 2 3 4 5 6 7 8 9 | #!/usr/bin/env ruby # TODO improve the line of code below # The line below is just a hack while we wait the delayed job guys answer the following issue # http://github.com/collectiveidea/delayed_job/issues#issue/38 ENV['RAILS_ENV'] ||= "production" require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) require 'delayed/command' Delayed::Command.new(ARGV).daemonize |
Como a flag -e production não estava sendo interpretada direito no Delayed Job, estou setando na mão o RAILS_ENV para production (linha 6), portanto estou supondo que você só está usando o Bluepill para monitorar processos do Delayed Job em environment igual a production.
Receita do Capistrano para o Bluepill
Para automatizar as tarefas de ligar e desligar o Bluepill, escrevi a seguinte receita de capistrano:
# deploy credentials set :user, "deploy" set :deploy_to, "/home/deploy/#{application}" set :use_sudo, false set :rails_env, "production" # Bluepill related tasks after "deploy:update", "bluepill:quit", "bluepill:start" namespace :bluepill do desc "Stop processes that bluepill is monitoring and quit bluepill" task :quit, :roles => [:app] do sudo "bluepill stop" sudo "bluepill quit" end desc "Load bluepill configuration and start it" task :start, :roles =>[:app] do sudo "bluepill load /home/deploy/my_app/current/config/production.pill" end desc "Prints bluepills monitored processes statuses" task :status, :roles => [:app] do sudo "bluepill status" end end
Note que ao invés de usar o método run do capistrano, estou usando o método sudo. Isso porque o comando bluepill deve ser rodado como root. Isso nos leva para o próximo tópico.
/etc/sudoers
Já que eu preciso rodar o comando bluepill como root, vou ter que mudar o meu set :user, "deploy" para set :user, "root"? Acho melhor não, não gostamos de dar acesso root para qualquer coisa, mesmo para deployment. Então, como fazer? Simples, basta editar seu arquivo de sudoers.
Para isso, você precisa usar o comando visudo para abrir e editar o arquivo /etc/sudoers. Uma vez com o arquivo aberto, adicione a seguinte linha no final do arquivo:
deploy ALL=(ALL) NOPASSWD: /usr/local/bin/bluepill
Pronto, agora o usuário deploy já pode fazer sudo bluepill sem precisar de senha. Problema resolvido sem colocar a segurança da sua máquina em risco.
Depois de ter feito esses 4 passos, você está pronto para dormir a noite sem se preocupar com seu processo do Delayed Job. E quando quando quiser saber como está o status dos seus processos monitorados, basta usar a seguinte task do capistrano na sua máquina local:
cap bluepill:status
E você? Quais soluções você usa para dormir em paz?
Update: Se você está tendo problemas em restartar o Bluepill com o capistrano, dê uma olhada aqui.
Posted in Português | Comments Off
As we already know, in Rails 3 all dependencies will be bundled. This means you will be able to use latest I18n version which includes several improvements by itself.
Besides that, a couple things changed on Rails 3 I18n, some features were added and others were deprecated. This post is a quick walkthrough it:
1) Error messages defaults
With the addition of ActiveModel, it’s easy to add I18n behavior to any object by simply including ActiveModel::Translation and ActiveModel::Validations. As side effect, if we followed the same translation pattern as in Rails 2.3, each ORM would have to specify its default error messages at #{ORM.name}.errors.messages. This means that if you are using two ORMs in your app, you would have to translate the same messages twice.
To handle this situation, error messages now has errors.attributes and errors.messages as fallbacks in case a message cannot be found for an specific ORM. Notice that this also allows you to customize a message for an specific attribute used by models in different ORMs. So if you have several models with title attribute, you can customize the blank message for them all by simply placing it at errors.attributes.title.blank.
2) Attributes default
In the same line as above, you can now specify default attributes across different models and ORMs as well. For example, if you are exposing created_at and updated_at in your views, until Rails 2.3 you needed to specify the same translation for each model. In Rails 3, you can simply do:
en:
attributes:
created_at: "Created at"
updated_at: "Updated at"3) f.submit
f.submit in forms now can be called without arguments and it will inspect the form object to set the proper label. Imagine the following form:
<% form_for @post do |f| %> <%= f.submit %> <% end %>
If @post is a new record, it will use “Create Post” as submit button label, otherwise, it uses “Update Post”. You can customize those labels with I18n under the following keys:
en:
helpers:
submit:
create: "Create a {{model}}"
update: "Confirm changes to {{model}}"Nonetheless, it also searches for keys under the object name key as well:
en:
helpers:
submit:
post:
create: "Add {{model}}"4) Labels with I18n
Labels were also updated to use I18n. Imagine the following form:
<% form_for @post do |f| %> <%= f.label :title %> <%= f.text_field :title %> <%= f.submit %> <% end %>
It will search for a label value at helpers.label.post.title, falling back to the value returned by Post.human_attribute_name(:title). This is useful in case you want more personalized labels instead of just “Title”.
5) Deprecation
Besides those improvements, I18n has two deprecations: the first is the key support.select should now be helpers.select and the other is that AV error messages are now agnostic, so activerecord.errors.template should now be errors.template.
That’s all, enjoy!
Tags: i18n, rails
Posted in English | 10 Comments »

All
English only
Em português apenas