Pergunta

Eu tenho luminárias com dados iniciais que precisa residir em meu banco de dados (países, regiões, transportadoras, etc.). Eu tenho um ancinho tarefa db: semente que vai semear um banco de dados

.
namespace :db do
  desc "Load seed fixtures (from db/fixtures) into the current environment's database." 
  task :seed => :environment do
    require 'active_record/fixtures'

    Dir.glob(RAILS_ROOT + '/db/fixtures/yamls/*.yml').each do |file|
      Fixtures.create_fixtures('db/fixtures/yamls', File.basename(file, '.*'))
    end
  end
end

Estou um pouco preocupado, porque esta tarefa limpa meu banco de dados limpo e carrega os dados iniciais. O fato de que isso é mesmo possível fazer mais do que uma vez na produção assusta o crap fora de mim. Isso é normal e eu só tenho que ser cauteloso? Ou será que as pessoas costumam proteger uma tarefa como esta, de alguma forma?

Foi útil?

Solução

Semeando dados com luminárias é uma péssima idéia.

Luminárias não são validados e desde desenvolvedores a maioria Rails não usar restrições de banco de dados Isso significa que você pode facilmente obter dados inválidos ou incompletos inserido no seu banco de dados de produção.

Luminárias também definir estranhos ids chave principal por padrão, o que não é necessariamente um problema, mas é irritante para trabalhar.

Há uma série de soluções para isso. Meu favorito pessoal é uma tarefa rake que executa um script Ruby que simplesmente usa ActiveRecord para inserir registros. Isto é o que o Rails 3 irá fazer com db:seed, mas você pode facilmente escrever este você mesmo.

Eu complementar isso com um método que eu adicionar ao ActiveRecord :: Base chamado create_or_update. Usando isso eu posso executar o script semente várias vezes, atualizando registros antigos, em vez de lançar uma exceção.

Eu escrevi um artigo sobre essas técnicas um tempo atrás chamado Carregando dados semente .

Outras dicas

Para a primeira parte da sua pergunta, sim, eu tinha acabado de colocar um pouco de precaução para a execução de uma tarefa como esta em produção. Eu coloquei uma proteção como este em minha bootstrapping / semeadura tarefa:

task :exit_or_continue_in_production? do
  if Rails.env.production?
    puts "!!!WARNING!!! This task will DESTROY " +
         "your production database and RESET all " +
         "application settings"
    puts "Continue? y/n"
    continue = STDIN.gets.chomp
    unless continue == 'y'
      puts "Exiting..."
      exit! 
    end
  end
end

Eu criei este essência por algum contexto.

Para a segunda parte da pergunta - geralmente você realmente quer duas coisas: a) muito facilmente semeando o banco de dados e configurar o aplicativo para o desenvolvimento, e b) bootstrapping o aplicativo no servidor de produção (como: inserção de usuário admin, criação de pastas aplicação depende, etc).

Eu usaria luminárias para semear em desenvolvimento - todos da equipe, então, vê os mesmos dados no aplicativo e o que está no aplicativo é consistente com o que está em testes. (Normalmente eu embrulhar rake app:bootstrap, rake app:seed rake gems:install, etc em rake app:install para que todos possam trabalhar no aplicativo por apenas clonar o repo e funcionando esta tarefa.)

Eu no entanto nunca use luminárias para semear / bootstrapping no servidor de produção. db/seed.rb Rails é realmente muito bem para esta tarefa, mas você pode, naturalmente, colocar a mesma lógica em sua própria tarefa rake app:seed, como outros apontou.

Rails 3 vai resolver isso para você usando um arquivo seed.rb.

http://github.com/brynary/rails/commit/4932f7b38f72104819022abca0c952ba6f9888cb

Nós construímos um monte de melhores práticas que utilizamos para a semeadura de dados. Nós dependem fortemente de semeadura, e temos alguns requisitos exclusivos uma vez que precisamos semear sistemas multi-tenant. Aqui estão algumas das melhores práticas que usamos:

  1. Luminárias não são a melhor solução, mas você ainda deve armazenar seus dados de sementes em algo diferente de Ruby. código Ruby para armazenar dados de sementes tende a ficar repetitivo e armazenar dados em um meio de arquivo analisáveis ??você pode escrever código genérico para lidar com suas sementes de uma forma consistente.
  2. Se você estiver indo para potencialmente sementes de atualização, use uma coluna marcador chamado algo como code para corresponder ao seu arquivo de sementes aos seus dados reais. Nunca confie em ids ser consistente entre os ambientes.
  3. Pense em como você deseja lidar com atualização de dados de sementes existentes. Existe algum potencial que os usuários se modificou esses dados? Se assim for, você deve manter as informações do usuário, em vez de ignorá-los com os dados semente?

Se você estiver interessado em algumas das maneiras que nós semear, nós embalados-los em uma jóia chamado SeedOMatic .

Como apenas cerca de excluir a tarefa fora de seu servidor de produção depois de ter semeado o banco de dados?

Eu só tinha uma ideia interessante ...

E se você criou \ db \ sementes \ e arquivos de estilo migração adicionados:

arquivo: 200907301234_add_us_states.rb

class AddUsStates < ActiveRecord::Seeds

  def up
    add_to(:states, [
      {:name => 'Wisconsin', :abbreviation => 'WI', :flower => 'someflower'},
      {:name => 'Louisiana', :abbreviation => 'LA', :flower => 'cypress tree'}
      ]
    end
  end

  def down
    remove_from(:states).based_on(:name).with_values('Wisconsin', 'Louisiana', ...)
  end
end

alternadamente:

  def up
    State.create!( :name => ... )
  end

Isso permitirá que você para executar migrações e sementes em uma ordem que lhes permitiria coexistir pacificamente mais.

pensamentos?

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