Pergunta

Eu tenho um aplicativo Rails onde os usuários precisam fazer login.Portanto, para que o aplicativo seja utilizável, deve haver um usuário inicial no sistema para a primeira pessoa fazer login (eles podem então criar usuários subsequentes).Até agora usei uma migração para adicionar um usuário especial ao banco de dados.

Depois de perguntar essa questão, parece que eu deveria usar db:schema:load, em vez de executar as migrações, para configurar novos bancos de dados em novas máquinas de desenvolvimento.Infelizmente, isso não parece incluir as migrações que inserem dados, apenas aquelas que configuram tabelas, chaves etc.

Minha pergunta é: qual é a melhor maneira de lidar com essa situação:

  1. Existe uma maneira de fazer com que d:s:l inclua migrações de inserção de dados?
  2. Eu não deveria usar migrações para inserir dados dessa maneira?
  3. Eu não deveria preencher previamente o banco de dados com dados?Devo atualizar o código do aplicativo para que ele lide com o caso em que não há usuários normalmente e permita que uma conta de usuário inicial seja criada ao vivo no aplicativo?
  4. Alguma outra opção?:)
Foi útil?

Solução 7

Pensei em resumir algumas das ótimas respostas que tive para essa pergunta, junto com meus próprios pensamentos, agora que li todas :)

Existem dois problemas distintos aqui:

  1. Devo preencher previamente o banco de dados com meu usuário 'admin' especial?Ou o aplicativo deveria fornecer uma forma de configuração quando for usado pela primeira vez?
  2. Como preencher previamente o banco de dados com dados?Observe que esta é uma pergunta válida, independentemente da resposta à parte 1:existem outros cenários de uso para pré-preenchimento além de um usuário administrador.

Para (1), parece que configurar o primeiro usuário dentro do próprio aplicativo é um trabalho extra, para funcionalidades que, por definição, quase nunca são usadas.No entanto, pode ser um pouco mais seguro, pois força o usuário a definir uma senha de sua escolha.A melhor solução está entre estes dois extremos:tenha um script (ou tarefa rake, ou qualquer outra coisa) para configurar o usuário inicial.O script pode então ser configurado para ser preenchido automaticamente com uma senha padrão durante o desenvolvimento e para exigir que uma senha seja inserida durante a instalação/implantação de produção (se você quiser desencorajar uma senha padrão para o administrador).

Para (2), parece que existem várias soluções boas e válidas.Uma tarefa de rake parece uma boa maneira, e existem alguns plugins para tornar isso ainda mais fácil.Basta dar uma olhada em algumas das outras respostas para ver os detalhes delas :)

Outras dicas

Experimente uma tarefa de rake.Por exemplo:

  1. Crie o arquivo /lib/tasks/bootstrap.rake
  2. No arquivo, adicione uma tarefa para criar seu usuário padrão:

    namespace :bootstrap do
      desc "Add the default user"
      task :default_user => :environment do
        User.create( :name => 'default', :password => 'password' )
      end

      desc "Create the default comment"
      task :default_comment => :environment do
        Comment.create( :title => 'Title', :body => 'First post!' )
      end

      desc "Run all bootstrapping tasks"
      task :all => [:default_user, :default_comment]
    end
  1. Então, ao configurar seu aplicativo pela primeira vez, você pode fazer rake db:migrate OU rake db:schema:load e, em seguida, rake bootstrap:all.

Usar db/seed.rb encontrado em todas as aplicações Rails.

Embora algumas respostas dadas acima de 2008 podem funcionar bem, eles estão bastante desatualizados e não são mais uma convenção Rails.

O preenchimento dos dados iniciais no banco de dados deve ser feito com db/seed.rb arquivo.

Funciona como um arquivo Ruby.

Para criar e salvar um objeto, você pode fazer algo como:

User.create(:username => "moot", :description => "king of /b/")

Depois de ter este arquivo pronto, você pode fazer o seguinte

rake db:migrate

rake db:seed

Ou em uma etapa

rake db:setup

Seu banco de dados deve ser preenchido com os objetos que você deseja criar em seed.rb

Eu recomendo que você não insira nenhum novo dados em migrações.Em vez disso, modifique apenas os dados existentes nas migrações.

Para inserir dados iniciais, recomendo usar YML.Em cada projeto Rails que eu configuro, eu crio um diretório fixtures no diretório DB.Em seguida, crio arquivos YML para os dados iniciais, assim como os arquivos YML são usados ​​para os dados de teste.Em seguida, adiciono uma nova tarefa para carregar os dados dos arquivos YML.

lib/tarefas/db.rake:

namespace :db do
  desc "This loads the development data."
  task :seed => :environment do
    require 'active_record/fixtures'
    Dir.glob(RAILS_ROOT + '/db/fixtures/*.yml').each do |file|
      base_name = File.basename(file, '.*')
      say "Loading #{base_name}..."
      Fixtures.create_fixtures('db/fixtures', base_name)
    end
  end

  desc "This drops the db, builds the db, and seeds the data."
  task :reseed => [:environment, 'db:reset', 'db:seed']
end

db/fixtures/users.yml:

test:
  customer_id: 1
  name: "Test Guy"
  email: "test@example.com"
  hashed_password: "656fc0b1c1d1681840816c68e1640f640c6ded12"
  salt: "188227600.754087929365988"

Esta é minha nova solução favorita, usando as gemas populator e faker:

http://railscasts.com/episodes/126-populating-a-database

Tente o semente-fu O plugin, que é um plugin bastante simples que permite propagar dados (e alterar esses dados iniciais no futuro), também permitirá propagar dados específicos do ambiente e dados para todos os ambientes.

Acho que a melhor opção é a número 3, principalmente porque dessa forma não haverá usuário padrão, o que é uma ótima maneira de inutilizar uma boa segurança.

Considere usar o console Rails.Bom para tarefas administrativas pontuais onde não vale a pena o esforço para configurar um script ou migração.

Na sua máquina de produção:

script/console production

...então ...

User.create(:name => "Whoever", :password => "whichever")

Se você estiver gerando esse usuário inicial mais de uma vez, também poderá adicionar um script em RAILS_ROOT/script/ e executá-lo na linha de comando em sua máquina de produção ou por meio de uma tarefa capistrano.

Essa tarefa Rake pode ser fornecida pelo plugin db-populate:

http://github.com/joshknowles/db-populate/tree/master

Ótima postagem no blog sobre isso:http://railspikes.com/2008/2/1/loading-seed-data

Eu estava usando as sugestões de Jay de um conjunto especial de fixtures, mas rapidamente me vi criando dados que não seriam possíveis usando os modelos diretamente (entradas não versionadas quando eu estava usando act_as_versioned)

Eu manteria isso em uma migração.Embora seja recomendado usar o esquema para configurações iniciais, a razão para isso é que ele é mais rápido, evitando problemas.Uma única migração extra para os dados deve servir.

Você também pode adicionar os dados ao arquivo de esquema, pois tem o mesmo formato das migrações.Você simplesmente perderia o recurso de geração automática.

Para usuários e grupos, a questão dos usuários pré-existentes deve ser definida com relação às necessidades da aplicação e não às contingências da programação.Talvez seu aplicativo exija um administrador;então pré-preencher.Ou talvez não - então adicione código para solicitar uma configuração do usuário no momento da inicialização do aplicativo.

Na questão mais geral, está claro que muitos aplicativos Rails podem se beneficiar de datas pré-preenchidas.Por exemplo, um pedido de retenção de endereço nos EUA também pode conter todos os estados e suas abreviações.Para esses casos, as migrações são suas amigas, acredito.

Algumas das respostas estão desatualizadas.Desde Rails 2.3.4, existe um recurso simples chamado Seed disponível em db/seed.rb :

#db/seed.rb
User.create( :name => 'default', :password => 'password' )
Comment.create( :title => 'Title', :body => 'First post!' )

Ele fornece uma nova tarefa rake que você pode usar após suas migrações para carregar dados:

rake db:seed

Seed.rb é um arquivo Ruby clássico, fique à vontade para usar qualquer estrutura de dados clássica (array, hashes, etc.) e iteradores para adicionar seus dados:

["bryan", "bill", "tom"].each do |name|
  User.create(:name => name, :password => "password")
end

Se quiser adicionar dados com caracteres UTF-8 (muito comuns em francês, espanhol, alemão, etc.), não esqueça de adicionar no início do arquivo:

# ruby encoding: utf-8

Este Railscast é uma boa introdução: http://railscasts.com/episodes/179-seed-data

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top