Si vous avez des colonnes de firebase database created_at
et updated_at
Rails updated_at
automatiquement ces valeurs lorsque vous créez et mettez à jour un object de modèle. Est-il possible de sauvegarder le modèle sans toucher à ces colonnes?
J’apporte certaines données existantes et j’aimerais définir ces valeurs à partir des valeurs correspondantes dans les champs de données hérités (autrement nommés). Je constate que lorsque je les place sur le modèle puis que vous enregistrez le modèle, Rails semble remplacer les valeurs entrantes.
Bien sûr, je pourrais simplement nommer les colonnes du modèle Rails différemment pour empêcher cela, mais une fois les données imscopes, je veux que Rails fasse son horodatage automatique.
Faites-le dans une tâche de migration ou de râteau (ou dans les nouvelles bases de données si vous êtes sur des rails latéraux):
ActiveRecord::Base.record_timestamps = false begin run_the_code_that_imports_the_data ensure ActiveRecord::Base.record_timestamps = true # don't forget to enable it again! end
Vous pouvez définir en toute sécurité created_at
et updated_at
manuellement, Rails ne se plaindra pas.
Remarque: Cela fonctionne également sur des modèles individuels, par exemple User.record_timestamps = false
utilisez plutôt la méthode update_column:
http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_column
update_column(name, value) # Updates a single atsortingbute of an object, without calling save.
La validation est ignorée.
Les rappels sont ignorés.
La colonne updated_at / updated_on n’est pas mise à jour si cette colonne est disponible.
Déclenche un ActiveRecordError lorsqu’il est appelé sur de nouveaux objects ou lorsque l’atsortingbut name est marqué en lecture seule.
Vous pouvez définir les éléments suivants dans votre migration:
ActiveRecord::Base.record_timestamps = false
Ou bien utilisez update_all:
update_all (updates, conditions = nil, options = {})
Met à jour tous les enregistrements avec les détails donnés s’ils correspondent à un ensemble de conditions fournies, les limites et la commande peuvent également être fournies. Cette méthode construit une seule instruction SQL UPDATE et l’envoie directement à la firebase database. Il n’instancie pas les modèles impliqués et ne déclenche pas de rappels Active Record.
Rails 5 offre un moyen pratique de mettre à jour un enregistrement sans mettre à jour son horodatage updated_at
.
Vous avez juste besoin de passer au touch:false
lors de la mise à jour de votre enregistrement.
>> user = User.first >> user.updated_at => Thu, 28 Apr 2016 20:01:57 IST +05:30 >> user.name = "Jose" >> user.save(touch: false) => true >> user.updated_at => Thu, 28 Apr 2016 20:01:57 IST +05:30
Dans Rails 3+, pour un seul object, définissez record_timestamps
pour l’object plutôt que la classe. C’est à dire,
>> user = User.first >> user.updated_at => Tue, 12 Apr 2016 22:47:51 GMT +00:00 >> user.name = "Jose" => "Jose" >> user.record_timestamps = false >> user.save => true >> user.updated_at => Tue, 12 Apr 2016 22:47:51 GMT +00:00 >> User.record_timestamps => true
De cette façon, vous ne touchez pas à l’état global du modèle, et vous n’avez pas à vous souvenir de restaurer le paramètre précédent dans un bloc d’ ensure
.
Comme il s’agit d’une importation unique, vous pouvez effectuer les opérations suivantes:
legacy_created_at
et legacy_updated_at
. #save
et ne vous #save
généralement pas de l’utilisation de update_all
ou similaire, et vous pouvez utiliser des rappels si vous le souhaitez. created_at
et updated_at
. Lorsque vous ne vous trouvez pas dans une importation en bloc, vous pouvez remplacer les valeurs de que méthode sur votre modèle pour append de nouvelles vérifications sur la mise à jour de la colonne updated_at.
J’aime utiliser un module mixin pour désactiver temporairement l’horodatage dans un bloc:
module WithoutTimestamps def without_timestamps old = ActiveRecord::Base.record_timestamps ActiveRecord::Base.record_timestamps = false begin yield ensure ActiveRecord::Base.record_timestamps = old end end end
Ensuite, vous pouvez l’utiliser partout où vous en avez besoin
class MyModel < ActiveRecord::Base include WithoutTimestamps def save_without_timestamps without_timestamps do save! end end end
Ou simplement une chose comme celle-ci:
m = MyModel.find(1) WithoutTimestamps.without_timestamps do m.save! end
En me référant à d’autres réponses, j’ai constaté à ma grande surprise que la désactivation des horodatages pour un seul modèle, comme dans:
User.record_timestamps = false
travaillé pour ma firebase database de développement, mais pas sur ma firebase database de pré-production, qui fonctionne sur un autre serveur. Cependant, cela fonctionne si je désactive les horodatages pour tous les modèles avec
ActiveRecord::Base.record_timestamps = false
(Situation: modification de l’atsortingbut created_at dans une migration)
Ou, pour la sécurité des threads, voir: http://www.hungryfools.com/2007/07/turning-off-activerecord-timestamp.html
Je n’ai pas réussi à faire en ActiveRecord::Base.record_timestamps
indicateurs ActiveRecord::Base.record_timestamps
changent quoi que ce soit, et le seul moyen de travailler est d’utiliser ActiveRecord::Base.no_touching {}
:
ActiveRecord::Base.no_touching do Project.first.touch # does nothing Message.first.touch # does nothing end Project.no_touching do Project.first.touch # does nothing Message.first.touch # works, but does not touch the associated project end
Pris d’ ici
Ceci est très utile pour les tâches de rake où vous devez remplacer certaines propriétés de modèles profondément liés et ne pas vous soucier des rappels internes, alors que vos utilisateurs s’appuient sur les atsortingbuts created_at
ou updated_at
ou ceux utilisés comme colonnes de sorting.