Ruby on Rails 2.1 - Scaffolding

Enquanto você está desenvolvendo aplicações Rails, especialmente aquelas que fornecem principalmente uma interface simples para dados em um banco de dados, muitas vezes pode ser útil usar o método scaffold.

Scaffolding oferece mais do que emoções de demonstração baratas. Aqui estão alguns benefícios -

  • Você pode obter o código rapidamente para seus usuários para feedback.

  • Você é motivado por um sucesso mais rápido.

  • Você pode aprender como o Rails funciona examinando o código gerado.

  • Você pode usar o andaime como base para iniciar seu desenvolvimento.

Exemplo de andaime

Ruby on Rails 2.0 muda a maneira como Rails usa scaffolding. Para entender o scaffolding , vamos criar um banco de dados chamadocookbook e uma mesa chamada recipes. -

Criando um aplicativo da Web Rails vazio

Abra uma janela de comando e navegue até onde deseja criar este cookbookaplicativo da web. Usamos c: \ ruby. Execute o seguinte comando para criar uma estrutura de diretório completa e o banco de dados MySQL do arquivo .yml necessário .

C:\ruby> rails -d mysql cookbook

Aqui estamos usando -d mysqlopção para especificar nosso interesse em usar o banco de dados MySQL. Podemos especificar qualquer outro nome de banco de dados como oracle ou postgress usando-dopção. Por padrão, o Rails usaSQLite base de dados.

Configurando o Banco de Dados

Aqui está a maneira de criar banco de dados -

mysql> create database cookbook;
Query OK, 1 row affected (0.01 sec)

mysql> grant all privileges on cookbook.*
 to 'root'@'localhost' identified by 'password';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Para instruir o Rails a localizar o banco de dados, edite o arquivo de configuração ~ \ cookbook \ config \ database.yml e mude o nome do banco de dados para cookbook. Quando terminar, deve ser o seguinte -

development:
   adapter: mysql
   encoding: utf8
   database: cookbook
   username: root
   password: password
   host: localhost
test:
   adapter: mysql
   encoding: utf8
   database: cookbook
   username: root
   password: password
   host: localhost
production:
   adapter: mysql
   encoding: utf8
   database: cookbook
   username: root
   password: password
   host: localhost

NOTE - Você pode usar configurações semelhantes para outros adaptadores de banco de dados no caso de desejar usar qualquer outro banco de dados, exceto MySQL.

O Rails permite que você execute no modo de desenvolvimento, modo de teste ou modo de produção, usando diferentes bancos de dados. Este aplicativo usa o mesmo banco de dados para cada um.

Definição da tabela de banco de dados

Supondo a seguinte estrutura para nosso recipes mesa -

id INT(11) 
title VARCHAR(40)
chef VARCHAR(40)
instructions VARCHAR(255)

O código de andaime gerado

Com a ação de cadafalso , o Rails gera todo o código de que precisa dinamicamente. Executando o scaffold como um script, gere o modelo, mais o scaffolding e o script de migração de banco de dados necessário, bem como um controlador, auxiliar e arquivos de suporte de teste da seguinte maneira -

cookbook> ruby script/generate scaffold Recipe title:string \
chef:string instructions:text

Anote um nome no singular Receita para criar receitas com nomes de mesa no plural . No entanto, o comando acima irá gerar as seguintes mensagens -

exists  app/models/
   exists  app/controllers/
   exists  app/helpers/
   create  app/views/recipes
   exists  app/views/layouts/
   exists  test/functional/
   exists  test/unit/
   exists  public/stylesheets/
   create  app/views/recipes/index.html.erb
   create  app/views/recipes/show.html.erb
   create  app/views/recipes/new.html.erb
   create  app/views/recipes/edit.html.erb
   create  app/views/layouts/recipes.html.erb
   create  public/stylesheets/scaffold.css
   create  app/controllers/recipes_controller.rb
   create  test/functional/recipes_controller_test.rb
   create  app/helpers/recipes_helper.rb
   route  map.resources :recipes
dependency  model
   exists    app/models/
   exists    test/unit/
   exists    test/fixtures/
   create    app/models/recipe.rb
   create    test/unit/recipe_test.rb
   create    test/fixtures/recipes.yml
   create    db/migrate
   create    db/migrate/20080614192220_create_recipes.rb
cookbook>

Agora, vamos examinar o que aconteceu nos bastidores.

O controlador

Vejamos o código por trás do controlador. Este código é gerado peloscaffoldgerador. Se você abrir app / controllers / recipes_controller.rb, encontrará algo da seguinte maneira -

class RecipesController < ApplicationController
   # GET /recipes
   # GET /recipes.xml
   def index
      @recipes = Recipe.find(:all)

      respond_to do |format|
         format.html # index.html.erb
         format.xml  { render :xml => @recipes }
      end
   end

   # GET /recipes/1
   # GET /recipes/1.xml
   def show
      @recipe = Recipe.find(params[:id])

      respond_to do |format|
         format.html # show.html.erb
         format.xml  { render :xml => @recipe }
      end
   end

   # GET /recipes/new
   # GET /recipes/new.xml
   def new
      @recipe = Recipe.new

      respond_to do |format|
         format.html # new.html.erb
         format.xml  { render :xml => @recipe }
      end
   end

   # GET /recipes/1/edit
   def edit
      @recipe = Recipe.find(params[:id])
   end

   # POST /recipes
   # POST /recipes.xml
   def create
      @recipe = Recipe.new(params[:recipe])

      respond_to do |format|
      if @recipe.save
         flash[:notice] = 'Recipe was successfully created.'
         format.html { redirect_to(@recipe) }
         format.xml  { render :xml => 
            @recipe, :status => :created, :location => @recipe }
      else
         format.html { render :action => "new" }
         format.xml  { render :xml => 
            @recipe.errors, :status => :unprocessable_entity }
         end
      end
   end

   # PUT /recipes/1
   # PUT /recipes/1.xml
   def update
   @recipe = Recipe.find(params[:id])

   respond_to do |format|
      if @recipe.update_attributes(params[:recipe])
         flash[:notice] = 'Recipe was successfully updated.'
         format.html { redirect_to(@recipe) }
         format.xml  { head :ok }
      else
         format.html { render :action => "edit" }
         format.xml  { render :xml => @recipe.errors, 
                      :status => :unprocessable_entity }
      end

   end

   # DELETE /recipes/1
   # DELETE /recipes/1.xml
   def destroy
      @recipe = Recipe.find(params[:id])
      @recipe.destroy
      
      respond_to do |format|
         format.html { redirect_to(recipes_url) }
         format.xml  { head :ok }
      end
   end
end

Este arquivo possui todos os métodos implementados automaticamente. Você pode realizar qualquer operação Criar, Ler, Excluir ou Editar usando estes métodos disponíveis.

Quando um usuário de uma aplicação Rails seleciona uma ação, por exemplo, "Mostrar" - o controlador irá executar qualquer código na seção apropriada - "def show" - e então por padrão irá renderizar um template com o mesmo nome - "show.html .erb ". Esse comportamento padrão pode ser sobrescrito sobrescrevendo o código em qualquer modelo. -

O controlador usa métodos ActiveRecord como find, find_all, new, save, update_attributes e destroy para mover dados de e para as tabelas do banco de dados. Note que você não precisa escrever nenhuma instrução SQL, o Rails cuidará disso automaticamente.

As visualizações

Todas as visualizações e métodos de controlador correspondentes são criados por scaffoldcomando e eles estão disponíveis no diretório app / views / recipes. Você terá os seguintes arquivos neste diretório -

  • index.html.erb - Este é o arquivo de modelo para mostrar a página padrão e será executado quando você digitar http://127.0.0.1:3000/recipes.

  • new.html.erb - Este é o modelo para criar uma nova receita e será executado sempre que você tentar criar uma nova receita.

  • show.html.erb - Este é o modelo para mostrar todas as receitas em seu banco de dados e será executado sempre que você tentar ver todas as receitas.

  • edit.html.erb - Este é o modelo para editar qualquer receita em seu banco de dados e será executado sempre que você tentar editar qualquer receita.

Sugerimos que você abra esses arquivos um por um e tente entender seu código-fonte.

As migrações

Você encontrará um arquivo de migração criado em ~/cookbook/db/migratesubdiretório. Este arquivo terá o seguinte conteúdo -

class CreateRecipes < ActiveRecord::Migration
   def self.up
      create_table :recipes do |t|
         t.string :title
         t.string :chef
         t.text :instructions
         t.timestamps
      end
   end

   def self.down
      drop_table :recipes
   end
end

Para criar o arquivo necessário em seu banco de dados, use o script auxiliar da seguinte maneira.

cookbook> rake db:migrate

Este comando irá criar recipes e schema_migrations mesas em seu cookbookbase de dados. Antes de continuar, certifique-se de que a tabela necessária foi criada com sucesso em seu banco de dados.

Pronto para testar

Todas as etapas acima dão vida à sua tabela de banco de dados. Ele fornece uma interface simples para seus dados e maneiras de -

  • Criação de novas entradas
  • Editando entradas atuais
  • Visualizando entradas atuais
  • Destruindo entradas atuais

Ao criar ou editar uma entrada, o scaffold fará todo o trabalho árduo de geração e manuseio do formulário. Ele até fornecerá geração inteligente de formulários, suportando os seguintes tipos de entradas -

  • Strings de texto simples
  • Áreas de texto (ou grandes blocos de texto)
  • Seletores de data
  • Seletores de data e hora

Agora, vá para o diretório do livro de receitas e execute o servidor da Web usando o seguinte comando -

cookbook> ruby script/server

Agora, abra um navegador e navegue para http://127.0.0.1:3000/recipes/new. Ele irá fornecer a você uma tela para criar novas entradas na tabela de receitas. Uma captura de tela é mostrada abaixo -

Agora, insira alguns valores nas caixas de texto fornecidas e pressione o botão Criar para criar uma nova receita. Seu registro é adicionado à tabela de receitas e mostra o seguinte resultado -

Você pode usar o Edit opção de editar a receita ou o Backbotão para ir para a página anterior. Supondo que você tenha pressionado oBackbotão, ele irá mostrar todas as receitas disponíveis em seu banco de dados. Como temos apenas um registro em nosso banco de dados, ele mostrará a seguinte tela -

Esta tela oferece a opção de ver os detalhes completos da tabela de receitas. Além disso, oferece opções para editar ou até mesmo excluir a tabela.

Aprimorando o modelo

O Rails oferece muito tratamento de erros de graça. Para entender isso, adicione algumas regras de validação ao modelo de receita vazio -

Modificar ~/cookbook/app/models/recipe.rb como segue e, em seguida, teste seu aplicativo -

class Recipe < ActiveRecord::Base
   validates_length_of :title, :within => 1..20
   validates_uniqueness_of :title, :message => "already exists"
end

Essas entradas darão verificação automática, como -

  • validates_length_of - O campo não está em branco e não é muito longo.

  • validates_uniqueness_of- Valores duplicados são capturados. Em vez da mensagem de erro padrão do Rails, fornecemos nossa mensagem personalizada.

Aqui, estamos tentando fornecer um título maior durante a edição do registro existente. Ele produz a seguinte mensagem de erro, apenas porque adicionamos as validações acima -

Como o andaime é diferente?

Se você leu os capítulos anteriores, deve ter visto que criamos métodos para listar, mostrar, excluir e criar dados, mas o scaffolding faz esse trabalho automaticamente.