Eu crio um novo registro assim:
truck = Truck.create(:name=>name, :user_id=>2)
Meu banco de dados atualmente tem vários milhares de entidades para caminhão, mas atribuí os ids a várias delas, de forma que deixei alguns ids disponíveis. Então o que está acontecendo é que o rails cria um item com id = 150 e funciona bem. Mas então ele tenta criar um item e atribuir a ele id = 151, mas esse id pode já existir, então estou vendo este erro:
ActiveRecord::RecordNotUnique (PG::Error: ERROR: duplicate key value violates unique constraint "companies_pkey"
DETAIL: Key (id)=(151) already exists.
E da próxima vez que eu executar a ação, ela simplesmente atribuirá o id 152, que funcionará bem se esse valor ainda não tiver sido usado. Como faço para que os trilhos verifiquem se um ID já existe antes de atribuí-lo?
Obrigado!
EDITAR
O ID do caminhão é o que está sendo duplicado. O usuário já existe e é uma constante neste caso. Na verdade, é um problema de legado com o qual tenho que lidar. Uma opção é recriar a tabela em let rails auto designar cada id desta vez. Estou começando a achar que essa pode ser a melhor escolha porque estou tendo alguns outros problemas, mas a migração para fazer isso seria muito complicada porque Truck é uma chave estrangeira em muitas outras tabelas. Haveria uma maneira simples de os trilhos criarem uma nova tabela com os mesmos dados já armazenados em Truck, com IDs atribuídos automaticamente e mantendo todos os relacionamentos existentes?
Respostas:
Rails provavelmente está usando a sequência embutida do PostgreSQL. A ideia de uma sequência é que ela seja usada apenas uma vez.
A solução mais simples é definir a sequência da coluna company.id para o valor mais alto da tabela com uma consulta como esta:
Estou supondo que seu nome de sequência "id_empresa_seq", nome da tabela "empresa" e nome da coluna "id" ... substitua-os pelos corretos. Você pode obter o nome da sequência com
SELECT pg_get_serial_sequence('tablename', 'columname');
ou examinar a definição da tabela com\d tablename
.Uma solução alternativa é substituir o método save () em sua classe de empresa para definir manualmente o id da empresa para novas linhas antes de salvar.
fonte
create table t (id serial not null primary key); insert into t values (1); insert into t values (default); ERROR: duplicate key value violates unique constraint "t_pkey" DETAIL: Key (id)=(1) already exists.
Fiz isso que resolveu o problema para mim.
Encontrei o reset_pk_sequence! deste tópico. http://www.ruby-forum.com/topic/64428
fonte
ActiveRecord::Base.connection.tables.each { |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) }
Com base na resposta @Apie .
Você pode fazer uma tarefa e executá-la quando precisar com:
Você cria tarefas como esta:
E no arquivo gerado (
lib/tasks/database.rake
) coloque:fonte
Parece-me um problema de banco de dados e não um problema de Rails. É possível que seu banco de dados tenha uma semente de identidade imprópria em sua
id
coluna? Para testar, tente fazer algumas inserções diretamente em seu banco de dados e veja se o mesmo comportamento existe.fonte
Resolvi esse problema seguindo o comando.
Execute isso em seu console de trilhos
fonte