Je veux faire une copie d'un enregistrement activerecord, en changeant un seul champ dans le processus (en plus de l' id ). Quelle est la manière la plus simple d'y parvenir?
Je me rends compte que je pourrais créer un nouvel enregistrement, puis itérer sur chacun des champs en copiant les données champ par champ - mais je me suis dit qu'il devait y avoir un moyen plus simple de le faire ...
tel que:
@newrecord=Record.copy(:id) *perhaps?*
q = p.clone
, puisp == q
jetrue
reviens. En revanche, si j'utiliseq = p.dup
, jefalse
reviens en les comparant.new?
méthode ne fonctionne pas.Selon vos besoins et votre style de programmation, vous pouvez également utiliser une combinaison de la nouvelle méthode de la classe et de la fusion. Faute d'un meilleur simple exemple , supposons qu'une tâche soit planifiée pour une certaine date et que vous souhaitiez la dupliquer à une autre date. Les attributs réels de la tâche ne sont pas importants, donc:
créera une nouvelle tâche avec
:id => nil
,:scheduled_on => some_new_date
et tous les autres attributs de la même chose que la tâche d' origine. En utilisant Task.new, vous devrez appeler explicitement save, donc si vous voulez qu'il soit enregistré automatiquement, changez Task.new en Task.create.Paix.
la source
WARNING: Can't mass-assign protected attributes: id, due_date, created_at, updated_at
retournéVous aimerez peut-être aussi la gemme Amoeba pour ActiveRecord 3.2.
Dans votre cas, vous souhaiterez probablement utiliser le
nullify
,regex
ouprefix
des options disponibles dans le DSL de configuration.Il prend en charge la duplication récursive facile et automatique
has_one
,has_many
et leshas_and_belongs_to_many
associations, le prétraitement sur le terrain et une configuration DSL hautement flexible et puissante qui peut être appliquée à la fois au modèle et à la volée.assurez-vous de consulter la documentation d'Amoeba mais l'utilisation est assez facile ...
juste
ou ajouter
à votre Gemfile
puis ajoutez le bloc amibe à votre modèle et exécutez la
dup
méthode comme d'habitudeVous pouvez également contrôler les champs qui seront copiés de nombreuses manières, mais par exemple, si vous vouliez empêcher la duplication des commentaires mais que vous vouliez conserver les mêmes balises, vous pourriez faire quelque chose comme ceci:
Vous pouvez également prétraiter les champs pour aider à indiquer l'unicité des préfixes et suffixes ainsi que des regex. En outre, il existe également de nombreuses options pour que vous puissiez écrire dans le style le plus lisible à votre intention:
La copie récursive des associations est facile, activez simplement l'amibe sur les modèles enfants
La configuration DSL a encore plus d'options, alors assurez-vous de consulter la documentation.
Prendre plaisir! :)
la source
.amoeba_dup
pas seulement.dup
. J'essayais d'exécuter ce code, mais cela ne fonctionnait pas ici.Utilisez ActiveRecord :: Base # dup si vous ne voulez pas copier l'identifiant
la source
.clone
Je copie généralement les attributs, en changeant tout ce que j'ai besoin de changer:
la source
unknown attribute
erreur avec une colonne à cause d'une colonne qui est là en raison d'une relation has_many. Y a-t-il un moyen de contourner cela?User.create(old_user.attributes.merge({ login: "newlogin", id: nil }))
. Cela permettra d'économiser un nouvel utilisateur avec l'ID unique correct.Si vous avez besoin d'une copie complète avec des associations, je recommande la gemme deep_cloneable .
la source
Dans Rails 5, vous pouvez simplement créer un objet en double ou enregistrer comme ceci.
la source
Le moyen le plus simple est:
Ou
la source
Voici un exemple de
#dup
méthode ActiveRecord prioritaire pour personnaliser la duplication d'instance et inclure également la duplication de relation:Remarque: cette méthode ne nécessite aucune gemme externe mais elle nécessite une version plus récente d'ActiveRecord avec la
#dup
méthode implémentéela source
Vous pouvez également vérifier la gemme actes_as_inheritable .
"Agit en tant qu'héritable est une gemme Ruby spécifiquement écrite pour les modèles Rails / ActiveRecord. Elle est destinée à être utilisée avec l'association auto-référentielle , ou avec un modèle dont un parent partage les attributs héritables. Cela vous permettra d'hériter de tout attribut ou relation du modèle parent. "
En ajoutant
acts_as_inheritable
à vos modèles, vous aurez accès à ces méthodes:inherit_attributes
inherit_relations
J'espère que cela peut vous aider.
la source
Puisqu'il pourrait y avoir plus de logique, lors de la duplication d'un modèle, je suggère de créer une nouvelle classe, où vous manipulez toute la logique nécessaire. Pour faciliter cela, il existe un joyau qui peut vous aider: clowne
Selon leurs exemples de documentation, pour un modèle utilisateur:
Vous créez votre classe de cloneur:
puis l'utiliser:
Exemple copié du projet, mais il donnera une vision claire de ce que vous pouvez réaliser.
Pour un enregistrement simple et rapide, je choisirais:
Model.new(Model.last.attributes.reject {|k,_v| k.to_s == 'id'}
la source