Validadores de modelo Rails interrompem migrações anteriores
-
09-06-2019 - |
Pergunta
Tenho uma sequência de migrações em um aplicativo Rails que inclui as seguintes etapas:
- Crie uma versão básica do modelo 'usuário'
- Crie uma instância deste modelo - é necessário que haja pelo menos um usuário inicial em meu sistema para que você possa fazer login e começar a usá-lo
- Atualize o modelo 'usuário' para adicionar um novo campo/coluna.
Agora estou usando "validates_inclusion_of" neste novo campo/coluna.Isso funcionou bem na minha máquina de desenvolvimento inicial, que já tinha um banco de dados com essas migrações aplicadas.No entanto, se eu for para uma máquina nova e executar todas as migrações, a etapa 2 falhará, porque valids_inclusion_of falhará, porque o campo da migração 3 ainda não foi adicionado à classe do modelo.
Como solução alternativa, posso comentar a linha "validates_...", executar as migrações e descomentá-la, mas isso não é legal.
Melhor seria reordenar minhas migrações para que a criação do usuário (etapa 2) fosse a última, após todas as colunas terem sido adicionadas.
Eu sou um novato em Rails, então pensei em perguntar qual é a maneira preferida de lidar com essa situação :)
Solução
A maneira mais fácil de evitar esse problema é usar rake db:schema:load na segunda máquina, em vez de db:migrate.D:S:L usa schema.rb para carregar a versão mais atual do seu esquema, em vez de migrá-lo do zero.
Se você se deparar com esse problema ao implantar em uma máquina de produção (onde a preservação dos dados é importante), provavelmente terá que consolidar suas migrações em um único arquivo sem conflitos.
Outras dicas
Você pode declarar uma classe com o mesmo nome dentro da migração, ela substituirá a do seu app/models:
class YourMigration < ActiveRecord::Migration
class User < ActiveRecord::Base; end
def self.up
# User.create(:name => 'admin')
end
end
Infelizmente, seu IDE pode tentar o preenchimento automático com base nesta classe (o Netbeans faz) e você não pode usar a lógica do seu modelo lá (exceto se você duplicá-lo).
Estou tendo que fazer isso agora.Com base no conselho de BiHi, estou carregando o modelo manualmente e redefinindo os métodos onde preciso.
load(File.join(RAILS_ROOT,"app/models/user.rb"))
class User < ActiveRecord::Base
def before_validation; nil; end # clear out the breaking before_validation
def column1; "hello"; end # satisfy validates_inclusion_of :column1
end