Desejo fazer uma cópia de um registro de registro ativo, alterando um único campo no processo (além do ID ). Qual é a maneira mais simples de conseguir isso?
Sei que poderia criar um novo registro e iterar sobre cada um dos campos que copiam os dados campo por campo - mas achei que deveria haver uma maneira mais fácil de fazer isso ...
tal como:
@newrecord=Record.copy(:id) *perhaps?*
q = p.clone
, e depoisp == q
, eu recebotrue
de volta. Por outro lado, se eu usarq = p.dup
,false
volto ao compará-las.new?
método não está funcionando.Dependendo das suas necessidades e estilo de programação, você também pode usar uma combinação do novo método da classe e mesclagem. Por falta de um exemplo simples e melhor , suponha que você tenha uma tarefa agendada para uma determinada data e deseje duplicá-la para outra data. Os atributos reais da tarefa não são importantes, portanto:
irá criar uma nova tarefa com
:id => nil
,:scheduled_on => some_new_date
e todos os outros atributos o mesmo que a tarefa original. Usando Task.new, você terá que chamar explicitamente salvar, portanto, se desejar salvá-lo automaticamente, altere Task.new para Task.create.Paz.
fonte
WARNING: Can't mass-assign protected attributes: id, due_date, created_at, updated_at
voltouVocê também pode gostar da gema Ameba do ActiveRecord 3.2.
No seu caso, você provavelmente vai querer fazer uso dos
nullify
,regex
ouprefix
opções disponíveis no DSL configuração.Ele suporta a duplicação fácil e automático recursiva
has_one
,has_many
ehas_and_belongs_to_many
associações, pré-processamento de campo e um DSL configuração altamente flexível e poderosa que pode ser aplicado tanto para o modelo e em tempo real.verifique a documentação da ameba, mas o uso é bastante fácil ...
somente
ou adicione
para o seu Gemfile
adicione o bloco de ameba ao seu modelo e execute o
dup
método como de costumeVocê também pode controlar quais campos são copiados de várias maneiras, mas, por exemplo, se você deseja impedir que os comentários sejam duplicados, mas deseja manter as mesmas tags, pode fazer algo assim:
Você também pode pré-processar os campos para ajudar a indicar exclusividade com prefixos e sufixos, além de expressões regulares. Além disso, também existem inúmeras opções para que você possa escrever no estilo mais legível para o seu propósito:
A cópia recursiva de associações é fácil, basta ativar a ameba em modelos infantis também
A configuração DSL tem ainda mais opções, portanto, verifique a documentação.
Aproveitar! :)
fonte
.amoeba_dup
, não apenas.dup
. Eu estava tentando executar esse código, mas não estava funcionando aqui.Use ActiveRecord :: Base # dup se você não quiser copiar o ID
fonte
.clone
Normalmente, apenas copio os atributos, alterando o que for necessário:
fonte
unknown attribute
erro com uma coluna devido a uma coluna que existe devido a um relacionamento has_many. Existe alguma maneira de contornar isso?User.create(old_user.attributes.merge({ login: "newlogin", id: nil }))
. Isso salvará um novo usuário com o ID exclusivo correto.Se você precisar de uma cópia profunda de associações, recomendo a gema deep_cloneable .
fonte
No Rails 5, você pode simplesmente criar objetos duplicados ou gravar assim.
fonte
A maneira mais fácil é:
Ou
fonte
Aqui está uma amostra do
#dup
método ActiveRecord de substituição para personalizar a duplicação de instância e incluir também a duplicação de relação:Nota: este método não requer nenhuma jóia externa, mas requer uma versão mais recente do ActiveRecord com o
#dup
método implementadofonte
Você também pode verificar o actions_as_inheritable gema .
"Atua como herdável é um Ruby Gem escrito especificamente para os modelos Rails / ActiveRecord. Ele deve ser usado com a Self-Referential Association ou com um modelo que tenha um pai que compartilhe os atributos herdáveis. Isso permitirá que você herde qualquer atributo ou relação do modelo pai ".
Adicionando
acts_as_inheritable
aos seus modelos, você terá acesso a estes métodos:herdit_attributes
herdit_relations
Espero que isso possa ajudá-lo.
fonte
Como poderia haver mais lógica, ao duplicar um modelo, sugiro criar uma nova classe, na qual você lida com toda a lógica necessária. Para facilitar isso, há uma jóia que pode ajudar: palhaço
Conforme seus exemplos de documentação, para um modelo de usuário:
Você cria sua classe cloner:
e depois use:
Exemplo copiado do projeto, mas fornecerá uma visão clara do que você pode alcançar.
Para um registro rápido e simples, eu usaria:
Model.new(Model.last.attributes.reject {|k,_v| k.to_s == 'id'}
fonte