RSS Feed

October, 2011

  1. Classes e Módulos – Variáveis de Classe e Variáveis de Instância de Classe.

    October 31, 2011 by urieljuliatti

    Estamos aí de novo para retomar nossos estudos de ruby. Hoje falarei sobre Variáveis de Classe e Variáveis de Instância. Mas..

    Antes de mais nada:

    Poderia ter deixado para o final, mas vale lembrar que semana que vem acontecerá a RubyConf Brasil, que ocorrerá dia 3 e 4 de novembro em São Paulo. Nem é uma questão de puro merchanda, mas vale a pena mesmo comparecer em um evento tão importante como esse. Além de encontrar profissionais da área e palestras de qualidade (feitas também por profissionais da área), tem toda a questão de fortalecer e acompanhar o crescimento da linguagem no Brasil. Veja o cast http://rubyconf2011.akitaonrails.com/br/speakers.html e me diga se você não se assustou com tamanha qualidade. (Detalhe pra quem curte: Se liga na camisa do Nick Sutterer hehehe).

    Pois é, muita coisa boa. As inscrições encerraram, mas vale a dica para o RubyConf do ano que vem. Provavelmente trarei um post aqui com a cobertura parcial do evento.

    Link do evento: http://rubyconf2011.akitaonrails.com/

    Rollback.

    Bem, agora vamos voltar com o ruby e falar um pouco sobre Variáveis de Classe.

    O que são Variáveis de Classe?

    Elas são visíveis e compartilhadas para os métodos de classe e os métodos de instância de uma classe e até mesmo pela definição da própria classe, em suma, com ela é possível que todos os objetos a compartilhem. Se você lembrar da programação tradicional, ela funciona como se fosse uma variável global. Assim como as variáveis de instância, as variáveis de classe são encapsuladas; podem ser usadas na implementação de uma classe, porém não permitem acesso direto. Em ruby, elas possuem a sintaxe marcada pelo @@.

    Uma maneira elegante de mostrar a sua utilização seria em um caso onde contabilizaríamos o número de objetos de uma classe que foram criados, por exemplo.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    class Test
     
       @@n = 0
     
       def initialize
           @@n += 1
       end
     
       def self.report
           puts "Number of objects created: #@@n"
       end
     
    end
    class Test
    
       @@n = 0
    
       def initialize
           @@n += 1
       end
    
       def self.report
           puts "Number of objects created: #@@n"
       end
    
    end

    Com o método de classe report, conseguimos obter um retorno com o número de objetos já criados:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    ruby-1.9.2-p136 :018 > t = Test.new
     => #
     
    ruby-1.9.2-p136 :019 > Test.report
    Number of objects created: 1
     => nil
     
    ruby-1.9.2-p136 :020 > Test.report
    Number of objects created: 1
     => nil
     
    ruby-1.9.2-p136 :022 > t = Test.new
     => #
     
    ruby-1.9.2-p136 :023 > Test.report
    Number of objects created: 2
     => nil
    ruby-1.9.2-p136 :018 > t = Test.new
     => #
    
    ruby-1.9.2-p136 :019 > Test.report
    Number of objects created: 1
     => nil
    
    ruby-1.9.2-p136 :020 > Test.report
    Number of objects created: 1
     => nil
    
    ruby-1.9.2-p136 :022 > t = Test.new
     => #
    
    ruby-1.9.2-p136 :023 > Test.report
    Number of objects created: 2
     => nil

    Variáveis de Instância de uma Classe

    Classes são objetos e podem ter variáveis de instância assim como os objetos podem ter. As variáveis de instância de uma classe – as vezes chamadas apenas de variáveis de instância de classe - não são a mesma coisa que variáveis de instância. Mas elas são parecidas o suficiente epodem também ser usadas ao invés das variáveis de classe.

    Uma variável de classe utilizada dentro de uma definição de classe e fora de um método de instância é uma variável de instância de uma classe.  Assim como variáveis ​​de classe, variáveis ​​de instância de classe são associadas com a classe do que com qualquer instância específica da classe.

    A desvantagem de usá-las é que elas não podem ser usadas dentro de métodos de instância como as variáveis de classe usam. Além dessa desvantagem, existe uma considerável possibilidade de confundir as variáveis de instância de classe com as variáveis de instância simples.

    Para ficar bem claro: As variáveis de instância são criadas quando você instancia a Classe e as variáveis de instância de classe são injetadas em tempo de execução, partindo do princípio de que o objeto já foi instanciado.

    Da mesma forma que as variáveis de instância, podemos utilizar attr, attr_reader e attr_accessor para criar métodos de acesso para elas. A única coisa que deve ser levada em consideração é que, para chamar esses métodos utilizados em metaprogramação no contexto certo.

    1
    2
    3
    
    class << self
          attr_accessor : n, : x, : y
    end
    class << self
          attr_accessor : n, : x, : y
    end

    Com esses acessores definidos, podemos fazer referências aos dados utilizados em Ponto.x, Ponto.y, Ponto.n :)

    Então rapazeada, ficamos nessa por aqui. Vou rumo a RubyConf que com certeza trará muito esclarecimento,
    conhecimento e novas experiências.

    Abraços!

    Referências Externas:

    http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

    http://sporkmonger.com/2007/2/19/instance-variables-class-variables-and-inheritance-in-ruby

    http://www.oreillynet.com/ruby/blog/2007/01/nubygems_dont_use_class_variab_1.html


  2. [Quick Post] – Construindo suas próprias tarefas com o Rake

    October 26, 2011 by urieljuliatti

    Muitos utilizam o rake sem ao menos saber o que ele é. Você mesmo já deve estar acostumado a rodar o comando rake db:migrate , certo?

    Bem, o objetivo desse post não é explicar em detalhes o que é o rake, mas sim em como customizá-lo. Portanto, de forma resumida, ele é nada mais do que uma gem que quando instalada utiliza-se do executável ‘rake’ para demandar suas tarefas. A idéia é de que funcionasse como o ‘make’ do Unix, ou seja, um Ruby Make, se assim posso dizer hehe. Contudo, entre piadinhas ruins a parte, o rake é responsável por executar tarefas em sua aplicação.

    O rails precisa que você executa o rake a partir da raiz do projeto para que ele acesse o seu RakeFile. Só por uma questão de investigação, abra o seu RakeFile:

    1
    2
    3
    4
    
    require File.expand_path('../config/application', __FILE__)
    require 'rake'
     
    Project::Application.load_tasks</pre>
    require File.expand_path('../config/application', __FILE__)
    require 'rake'
    
    Project::Application.load_tasks</pre>

    A partir daí, ele prepara o ‘ambiente’ para todas as tarefas que existirem, customizadas ou não.

    Customizando.

    O acesso que você possui para customizar tarefas é em /lib/tasks. Neste exemplo, vou mostrar como configurar uma tarefa de seed específico para um rake db:seed, veja o resultado:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    # libs/tasks/
    namespace :db do
       # poderia ser qualquer outra coisa que seguisse os padrões do :db
       namespace :seed do
          # qualquer coisa.
          task :galeria => :environment do
             #exemplo desabilitando uma galeria
             galeria = Attribute.find_by_name('Galeria')
             if galeria
                galeria.update_attributes(:code => 1, :name => "Galeria", :installed => 0)
                galeria.save
             end
         end
      end
    end
    # libs/tasks/
    namespace :db do
       # poderia ser qualquer outra coisa que seguisse os padrões do :db
       namespace :seed do
          # qualquer coisa.
          task :galeria => :environment do
             #exemplo desabilitando uma galeria
             galeria = Attribute.find_by_name('Galeria')
             if galeria
                galeria.update_attributes(:code => 1, :name => "Galeria", :installed => 0)
                galeria.save
             end
         end
      end
    end

    Ao executar rake db:seed:galeria, vou ter minha galeria desabilitada.

    É isso aí e até o próximo!

    Referências:

    http://databasically.com/2008/08/03/rake-list-tasks/ | Lista com várias tasks para :db

    http://www.tutorialspoint.com/ruby-on-rails/rails-and-rake.htm

    http://akitaonrails.com/2009/02/16/automatizando-tarefas-com-ruby-e-rake


  3. Classes e Módulos.

    October 25, 2011 by urieljuliatti

    Fala rapazeada, tudo na ‘sussabilidade’?!

    Pois é, vamos aqui seguindo mais um post para contribuir para essa longa e maravilhosa jornada que estou percorrendo com o ruby.

    Resolvi ir direto para um tema que estou tendo bastante curiosidade no momento, que é sobre Classes e Módulos com ruby, especialmente os módulos.

    Começarei com as Classes, cuja abordagem é vasta, podendo ser dividida em várias etapas. É bem capaz que eu resuma muita coisa, dando ênfase apenas as partes relevantes, mas sempre deixando algumas referências para acrescentar e talvez divida esse post em séries de posts, para facilitar a divisão dos tópicos.

    Antes de tudo.

    Como muitos de nós sabemos, Ruby  é uma linguagem puramente Orientada a Objetos, cada valor é (ou ao menos se comporta) como um objeto. Todo objeto é uma instância de uma classe. E uma classe define uma série de métodos que respondem a um objeto. Por convenção de arquitetura de software, uma classe pode extender ou ser uma subclasse de outras classes e herdar ou sobrescrever métodos de suas superclasses. Em Ruby, as classes também podem ter métodos herdados de módulos.

    Os objetos são estritamente encapsulados: Os estados só podem ser acessados por seus métodos já definidos. As variáveis de instância manipuladas por esses métodos não podem ser acessadas diretamente por fora do objeto. É possível gerar getters e setters, acessando diretamente o estado do objeto. Esses acessores são conhecidos como atributos são diferentes das variáveis de instância. A visibilidade dos métodos de uma classe podem ser definidas como “public”, “private” ou “protected” que afetam drásticamente na forma que eles são chamados.

    Ao contrário do que se pensa sobre as restrições geradas pelo encapsulamento de um estado do objeto, as classes em Ruby são bastante abertas. Qualquer programa em ruby pode adicionar métodos para classes já existentes e até mesmo métodos singleton para objetos específicos. É um conceito bem interessante, pois ao fazer:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    class Test
     
       def user(nome)
     
           nome ||= "João Padrão"
     
       end
     
    end
     
    # abrindo a mesma classe e editando-a novamente
     
    def Test
     
        def user(nome, cpf)
     
            nome ||= "Pedro Padrão"
     
            cpf ||= "106.778.900-90"
     
        end
     
    end
    class Test
    
       def user(nome)
    
           nome ||= "João Padrão"
    
       end
    
    end
    
    # abrindo a mesma classe e editando-a novamente
    
    def Test
    
        def user(nome, cpf)
    
            nome ||= "Pedro Padrão"
    
            cpf ||= "106.778.900-90"
    
        end
    
    end

    O que vamos fazer inicialmente é definir uma classe e seus métodos. Muita coisa aqui vai ser retomada posteriormente, com uma abordagem mais avançada :)

    Definindo uma classe.

    Baby Steps, é um conceito que meu amigo @m3nd3s sempre aconselha. Seguindo esse conselho, vamos dar início a esse tópico definindo uma classe bem boba, mas que aborda um aprendizado conciso.

    O que precisamos para criar uma classe? Definí-la. É tudo muito simples:

    1
    2
    3
    
    class Ponto
     
    end
    class Ponto
    
    end

    Com a palavra chave “class” definimos uma classe, seguindo pelo end, que fecha seu escopo. Não sei vocês observaram, a classe foi nomeada com a inicial maiúscula, é uma regra do Ruby, obrigatória por sinal. O nome da constante e o nome da classe são os mesmos, você verá isso posteriormente com mais detalhes.

    Instanciando.

    Mesmo se não colocarmos nada na classe Ponto, podemos instanciá-la:

    1
    2
    
    ruby-1.9.2-p290 :005 > p = Ponto.new
    => #<Ponto:0x00000106b99c70>
    ruby-1.9.2-p290 :005 > p = Ponto.new
    => #<Ponto:0x00000106b99c70>

    A constante Ponto mantêm em um objeto o que representa a nossa classe. Todos os objetos possuem um método chamado new que é responsável por criar uma nova instância. Não há muita coisa interessante a fazer com esse objeto que criamos, apenas verificar algo do tipo:

    1
    2
    3
    4
    5
    
    ruby-1.9.2-p290 :006 > p.class
    => Ponto
     
    ruby-1.9.2-p290 :008 > p.is_a?Ponto
    => true
    ruby-1.9.2-p290 :006 > p.class
    => Ponto
    
    ruby-1.9.2-p290 :008 > p.is_a?Ponto
    => true

    Inicializando.

    Se você veio de outras linguagens orientadas a objeto, certamente deve conhecer o termo “construtor”, é exatamente isso que
    o initialize faz.

    1
    2
    3
    4
    5
    6
    7
    
    class Ponto
     
       def initialize(x,y)
           @x, @y = x,y
       end
     
    end
    class Ponto
    
       def initialize(x,y)
           @x, @y = x,y
       end
    
    end

    Com esse método definido, podemos criar outros ponteiros e ver o seu retorno.

    1
    2
    3
    4
    5
    
    ruby-1.9.2-p290 :008 > p = Ponto.new(1,10)
     => #<Ponto:0x00000105dd6fc0 @x=1, @y=10>
     
    ruby-1.9.2-p290 :009 > p
     => #<Ponto:0x00000105dd6fc0 @x=1, @y=10>
    ruby-1.9.2-p290 :008 > p = Ponto.new(1,10)
     => #<Ponto:0x00000105dd6fc0 @x=1, @y=10>
    
    ruby-1.9.2-p290 :009 > p
     => #<Ponto:0x00000105dd6fc0 @x=1, @y=10>

    Repare bem nas variáveis de instância x e y, que ja foram inicializadas para o objeto corrente com o valor de 1 e 10 para x e y, respectivamente.
    Acessores e Atributos

    Como falei anteriormente, a classe Ponto utiliza duas variáveis de instância, contudo, o valor dessas variáveis estão acessiveis apenas para outros métodos de instância. Isto significa se quisermos que outros objetos da classe queiram utilizar métodos para acessar o valor de X e Y, teremos que fornecer métodos acessores que retornariam os valores dessas variáveis.

    Ao pé da letra, para quem vem de outras linguagens Orientadas a Objeto, faríamos assim:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    class Ponto
     
       def initialize(x,y)
           @x, @y = x,y
       end
     
       def x
          @x
       end
     
       def y
          @y
       end
     
    end
    class Ponto
    
       def initialize(x,y)
           @x, @y = x,y
       end
    
       def x
          @x
       end
    
       def y
          @y
       end
    
    end

    Uma vez definindo esses métodos, poderíamos fazer isso:

    1
    2
    3
    4
    5
    
    ruby-1.9.2-p290 :023 > p = Ponto.new(1,2)
     => #<Ponto:0x00000105db3700 @x=1, @y=2>
     
    ruby-1.9.2-p290 :024 > q = Ponto.new(p.x*2, p.y*3)
     => #<Ponto:0x00000105dab870 @x=2, @y=6>
    ruby-1.9.2-p290 :023 > p = Ponto.new(1,2)
     => #<Ponto:0x00000105db3700 @x=1, @y=2>
    
    ruby-1.9.2-p290 :024 > q = Ponto.new(p.x*2, p.y*3)
     => #<Ponto:0x00000105dab870 @x=2, @y=6>

    Agora, para fazermos um setter, faríamos algo do tipo:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    class Ponto
     
       def initialize(x,y)
           @x, @y = x,y
       end
     
       def x
          @x
       end
     
       def y
          @y
       end
     
       def x=(value)
           @x = value
       end
     
       def y=(value)
           @y = value
       end
     
    end
    class Ponto
    
       def initialize(x,y)
           @x, @y = x,y
       end
    
       def x
          @x
       end
    
       def y
          @y
       end
    
       def x=(value)
           @x = value
       end
    
       def y=(value)
           @y = value
       end
    
    end

    Dessa forma, modificaríamos o valor da variável de instância do objeto corrente da seguinte jeito:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    ruby-1.9.2-p290 :045 > p = Ponto.new(1,1)
     => #<Ponto:0x00000105d790f0 @x=1, @y=1>
     
    ruby-1.9.2-p290 :046 > p.x = 0
     => 0
     
    ruby-1.9.2-p290 :047 > p
     => #<Ponto:0x00000105d790f0 @x=0, @y=1>
     
    ruby-1.9.2-p290 :048 > p.y = 50
     => 50
     
    ruby-1.9.2-p290 :049 > p
     => #<Ponto:0x00000105d790f0 @x=0, @y=50>
    ruby-1.9.2-p290 :045 > p = Ponto.new(1,1)
     => #<Ponto:0x00000105d790f0 @x=1, @y=1>
    
    ruby-1.9.2-p290 :046 > p.x = 0
     => 0
    
    ruby-1.9.2-p290 :047 > p
     => #<Ponto:0x00000105d790f0 @x=0, @y=1>
    
    ruby-1.9.2-p290 :048 > p.y = 50
     => 50
    
    ruby-1.9.2-p290 :049 > p
     => #<Ponto:0x00000105d790f0 @x=0, @y=50>

    Porém, com ruby podemos simplificar a nossa vida, muitas vezes com apenas uma linha. Nesse exemplo, seguiremos o legado rubyway e faremos os getters e setters em apenas duas linhas:

    1
    2
    3
    4
    5
    
    class Ponto
     
       attr_accessor : x, :y
     
    end
    class Ponto
    
       attr_accessor : x, :y
    
    end

    Faça a mesma coisa agora no terminal para você ver o retorno:

    1
    2
    3
    4
    5
    6
    7
    8
    
    ruby-1.9.2-p290 :065 > p = Ponto.new(10,10)
     => #<Ponto:0x00000105d1a528 @x=10, @y=10>
     
    ruby-1.9.2-p290 :066 > p.x = 20
     => 20
     
    ruby-1.9.2-p290 :067 > p
     => #<Ponto:0x00000105d1a528 @x=20, @y=10>
    ruby-1.9.2-p290 :065 > p = Ponto.new(10,10)
     => #<Ponto:0x00000105d1a528 @x=10, @y=10>
    
    ruby-1.9.2-p290 :066 > p.x = 20
     => 20
    
    ruby-1.9.2-p290 :067 > p
     => #<Ponto:0x00000105d1a528 @x=20, @y=10>

    Existem os métodos attr_writer (setter), attr_reader (getter) e o que utilizamos, o attr_accessor (getter e setter), eles são responsáveis por criarem métodos de instância para nós :)

    Esse é um exemplo clássico de metaprogramação, e a habilidade de fazer isso é um dos maiores recursos que o ruby oferece.

    Métodos de Classe.

    Para quem já conhece a Orientação a Objetos, sabe que um método de classe pode ser acessado apenas pela própria classe seja lá onde ele for chamado. Isto é, no exemplo que estamos seguindo, o método de classe que vamos criar agora não é um método de instância que seria chamado em um objeto Ponto.

    A chamada para o método de classe seria algo como:

    1
    
    total = Ponto.soma(p1, p2,p3)
    total = Ponto.soma(p1, p2,p3)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    class Ponto
     
       attr_reader : x, :y
     
       def self.soma(*pontos)
           x = y = 0
           pontos.each {|p| x += p.x; y += p.y}
           Ponto.new(x,y)
       end
     
    end
    class Ponto
    
       attr_reader : x, :y
    
       def self.soma(*pontos)
           x = y = 0
           pontos.each {|p| x += p.x; y += p.y}
           Ponto.new(x,y)
       end
    
    end

    Dessa forma, estaremos acessando a soma de todos os x e y de cada ponto através de um método de classe :)

    Constantes.

    Várias classes podem ser beneficiadas por uma associação e definição de algumas constantes, eis um exemplo:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    class Ponto
     
    def initialize(x,y)
     
        @x, @y = x,y
     
    end
     
    ORIGEM = Ponto.new(0,0)
     
    COORD_X = Ponto.new(1,0)
     
    COORD_Y = Ponto.new(0,1)
     
    [...]
     
    end
    class Ponto
    
    def initialize(x,y)
    
        @x, @y = x,y
    
    end
    
    ORIGEM = Ponto.new(0,0)
    
    COORD_X = Ponto.new(1,0)
    
    COORD_Y = Ponto.new(0,1)
    
    [...]
    
    end

    Uma vez dentro da classe, as constantes podem ser acessadas pelos nomes, diretamente. Caso estejam fora, para serem acessadas, devem estar acompanhada no nome da classe, como no exemplo:

    1
    
    Ponto::COORD_X + PONTO::CORD_Y
    Ponto::COORD_X + PONTO::CORD_Y

    Você pode inicializar até mesmo fora da classe:

    1
    2
    
    ruby-1.9.2-p136 :206 > Ponto::COORD_X = Ponto.new(2,0)
     => #<Ponto:0x00000103bb2728 @x=2, @y=0>
    ruby-1.9.2-p136 :206 > Ponto::COORD_X = Ponto.new(2,0)
     => #<Ponto:0x00000103bb2728 @x=2, @y=0>

    O tópico é enorme, portanto, vou extendê-lo em outros posts. Para o próximo post trarei tópicos que abordam Variáveis de Classe, Variáveis de Instância e Visibilidade.

    Referências:

    http://www.ruby-doc.org/docs/ProgrammingRuby/html/classes.html

    http://www.devarticles.com/c/a/Ruby-on-Rails/Ruby-Classes-and-Objects/

    http://blog.bluesoft.com.br/ruby-classes-e-objetos/


  4. [Quick Post] – Migrations Para Models Já Existentes.

    October 21, 2011 by urieljuliatti

    Fala pessoal, beleza? Hoje vou demonstrar rapidamente sobre migrations para modelos já existentes.

    A necessidade surgiu quando tive a necessidade de criar um campo/atributo booleano para um modelo já existente.

    Presume-se que você já tenha um modelo, no meu caso é o User, que possui apenas um atributo “name” e “email.

    O Rails fornece um recurso interessante: Migrations, que vai te ajudar bastante a organizar sua base de dados e todo o fluxo possível.

    Para criar uma migration para um model existente você fará assim:

    1
    
    rails g migration AddHiddenToUser hidden:boolean
    rails g migration AddHiddenToUser hidden:boolean

    Onde o hidden será o campo novo para o modelo User que já existe. O console trará o seguinte:

    1
    2
    
    invoke  active_record
    create    db/migrate/20111021182503_add_hidden_to_user.rb
    invoke  active_record
    create    db/migrate/20111021182503_add_hidden_to_user.rb

    Ele chama o Active Record e cria um arquivo baseado na linha que você digitou. Aproveite e abra a sua migration gerada, logo você obterá:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    class AddHiddenToUser < ActiveRecord::Migration
     
    def self.up
     
    add_column :users, :hidden, :boolean
     
    end
     
    def self.down
     
    remove_column :users, :hidden
     
    end
     
    end
    class AddHiddenToUser < ActiveRecord::Migration
    
    def self.up
    
    add_column :users, :hidden, :boolean
    
    end
    
    def self.down
    
    remove_column :users, :hidden
    
    end
    
    end

    Lindo! O Rails reconheceu que você quer adicionar um atributo do tipo boolean para uma tabela Users (add_column :users, :hidden, :boolean)

    Até agora o rails fez todo o esqueleto, porém nada ainda funciona. Para isso funcionar, você vai ter que rodar um rake db:migrate, onde o rails executa uma função que adiciona literalmente o atributo “hidden” a sua tabela Users.

    Veja o log após a execução do comando:

    1
    2
    3
    4
    
    <pre>==  AddHiddenToUser: migrating ================================================
    -- add_column(:users, :hidden, :boolean)
       -> 0.0081s
    ==  AddHiddenToUser: migrated (0.0082s) =======================================</pre>
    <pre>==  AddHiddenToUser: migrating ================================================
    -- add_column(:users, :hidden, :boolean)
       -> 0.0081s
    ==  AddHiddenToUser: migrated (0.0082s) =======================================</pre>

    Lindezidade total, hein?

    Para finalizar, basta adicionar o field na view:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    <pre><%= form_for(@user) do |f| %>
      <%= render "shared/error_messages", :target => @user %>
     
      <div class="field">
        <%= f.label :name %><%= mark_required(@user, :name) %><br />
        <%= f.text_field :name %>
      </div>
      <div class="field">
        <%= f.label :email %><%= mark_required(@user, :email) %><br />
        <%= f.text_field :email %>
      </div>
     <div class="field"></strong>
         <%= f.label :hidden %><br />
         <%= f.check_box :hidden %>
     </div>
      <div class="actions">
        <%= f.submit %>
      </div>
    <% end %>
    <pre><%= form_for(@user) do |f| %>
      <%= render "shared/error_messages", :target => @user %>
    
      <div class="field">
        <%= f.label :name %><%= mark_required(@user, :name) %><br />
        <%= f.text_field :name %>
      </div>
      <div class="field">
        <%= f.label :email %><%= mark_required(@user, :email) %><br />
        <%= f.text_field :email %>
      </div>
     <div class="field"></strong>
         <%= f.label :hidden %><br />
         <%= f.check_box :hidden %>
     </div>
      <div class="actions">
        <%= f.submit %>
      </div>
    <% end %>

    Antes de concluir, um detalhe importante que percebi ao implementar essa funcionalidade é que o Rails fornece funcionalidades bacanas ao acrescentar uma migration dessa forma. Abra o seu console e teste da seguinte forma:

    1
    2
    3
    4
    
    ruby-1.9.2-p136 :004 > user = User.first
     => #<User id: 1, name: "Uriel", email: "uriel.juliattivalle@gmail.com", created_at: "2011-10-21 18:39:36", updated_at: "2011-10-21 18:39:36", hidden: true>
    ruby-1.9.2-p136 :005 > user.hidden?
     => true
    ruby-1.9.2-p136 :004 > user = User.first
     => #<User id: 1, name: "Uriel", email: "uriel.juliattivalle@gmail.com", created_at: "2011-10-21 18:39:36", updated_at: "2011-10-21 18:39:36", hidden: true>
    ruby-1.9.2-p136 :005 > user.hidden?
     => true

    Uma vez que seu atributo é do tipo Boolean, o rails fornece um helper method chamado “hidden?” que retorna true ou false. Muito útil, uma vez que outras situações teríamos que fazê-lo na mão, apesar de simples tomaria um certo tempo.

    Semana que vem tem RubyConf2011! Ainda dá tempo de se cadastrar http://rubyconf2011.akitaonrails.com/en/

    É isso aí rapazeada, vamo que vamo!