Comment garder trace de l'histoire du modèle avec la table de mappage dans Ruby on Rails?
rêve
Je tiens à garder une trace de quand un utilisateur change son adresse.
De cette façon, quand une commande est passée, elle sera toujours en mesure de référencer l'adresse de l'utilisateur qui a été utilisé au moment de la passation de commande.
possible de schéma
users (
id
username
email
...
)
user_addresses (
id
label
line_1
line_2
city
state
zip
...
)
user_addresses_map (
user_id
user_address_id
start_time
end_time
)
orders (
id
user_id
user_address_id
order_status_id
...
created_at
updated_at
)
en sql, cela pourrait ressembler à quelque chose comme: [sql]
select ua.*
from orders o
join users u
on u.id = o.user_id
join user_addressses_map uam
on uam.user_id = u.id
and uam.user_address_id = o.user_address_id
join user_addresses ua
on ua.id = uam.user_address_id
and uam.start_time < o.created_at
and (uam.end_time >= o.created_at or uam.end_time is null)
;
edit: La Solution
@KandadaBoggu posté une excellente solution. Le Vestale Versions du plugin est un excellente solution.
extrait de code ci-dessous prise de http://github.com/laserlemon/vestal_versions
Enfin, SÈCHE ActiveRecord gestion des versions!
acts_as_versioned par technoweenie était un bon début, mais il a omis de conserver avec ActiveRecord de l'introduction de la sale des objets dans la version 2.1. En outre, chaque versionnées modèle a besoin de ses propres versions de table qui duplique le plus de l'original colonnes de la table. Les versions de table est ensuite rempli avec les enregistrements qui souvent reproduire la plupart de l'enregistrement d'origine attributs. Dans l'ensemble, pas très SÈCHE.
vestal_versions ne nécessite qu'une des versions de la table (polymorphically associé avec ses parents modèles) et aucun changement que ce soit à des tables existantes. Mais il fait un pas de sèche-linge en stockant une sérialisé de hachage de seulement modèles de changements. Pensez modernes systèmes de contrôle de version. En parcourant le dossier des changements, les modèles peuvent être ramenés à un point quelconque dans le temps.
Et c'est exactement ce que vestal_versions. Pas seulement un modèle d'être revenu à un précédent numéro de version, mais aussi pour une date ou une heure!
source d'informationauteur maček
Vous devez vous connecter pour publier un commentaire.
Utiliser le Vestale versions du plugin pour cela:
Reportez-vous à cette écran en fonte pour plus de détails.
J'ai pensé ajouter une mise à jour de réponse. Semble que le
paper_trail
gem est devenu le plus populaire pour la gestion des versions dans les Rails. Il prend en charge Rails 4.https://github.com/airblade/paper_trail
De leur readme:
Pour l'installation et l'installer:
D'Utilisation De Base:
Pour une instance spécifique de la
Widget
classe:J'ai seulement joué avec elle, mais je suis sur le point de commencer une assez ambitieux site qui nécessite une bonne gestion des versions de certaines classes et j'ai décidé d'utiliser
paper_trail
.===EDIT====
J'ai mis en œuvre la
paper_trail
joyau de la production à la http://www.muusical.com et il a bien fonctionné à l'aide de la ci-dessus. Le seul changement est que je suis en utilisantgem 'paper_trail', '~> 4.0.0.rc'
dans monGemfile
.À partir d'une architecture de données de point de vue, je suggère que, pour résoudre votre problème de
... il vous suffit de copier l'adresse de la personne dans une Commande de modèle. Les éléments seraient en OrderItem modèle. Je voudrais reformuler la question comme "Un ordre arrive à un point dans le temps. Le OrderHeader comprend toutes les données pertinentes à ce point dans le temps."
Est-il pas normal?
Non, parce que le OrderHeader représente un point dans le temps, ne continue pas "la vérité".
Ci-dessus est un moyen standard de manipulation afin de l'en-tête de données et supprime beaucoup de complexité à partir de votre schéma plutôt que pour le suivi de toutes les modifications dans un modèle.
- S'en tenir à une solution qui résout le problème réel, pas possible les problèmes-t-on besoin d'un historique des modifications de l'utilisateur? Ou avez-vous juste besoin de l'ordre des en-têtes de refléter la réalité de l'ordre lui-même?
Ajouté: Et notez que vous devez savoir qui adresse a finalement été utilisé pour expédier la commande/facture. Vous ne voulez pas regarder à un ordre ancien et consultez le guide de l' actuel adresse, vous voulez voir l'adresse que l'ordre utilisé lorsque la commande a été expédiée. Voir mon commentaire ci-dessous pour en savoir plus sur cette.
Rappelez-vous que, en fin de compte, le but du système est de modéliser le monde réel. Dans le monde réel, une fois que la commande est imprimé et envoyé les marchandises commandées, le navire n'est pas de changer. Si vous envoyez doux biens ou des services, alors vous avez besoin d'extrapoler à partir de l'exemple facile.
Systèmes d'ordre sont un excellent cas où il est très important de comprendre les besoins de l'entreprise et réalités, ne vous contentez pas de parler avec les dirigeants de l'entreprise, aussi parler à l'avant-vente en ligne de personnes, commis de commande, les comptes débiteurs de commis, de l'expédition dept gens, etc.
Vous êtes à la recherche pour le acts_as_audited plugin. Il fournit un tableau sur les vérifications et le modèle pour être utilisé à la place de votre carte.
Configurer exécuter la migration et ajoutez ce qui suit à votre adresse de l'utilisateur modèle.
Une fois que vous avez configuré, tout ce que vous devez faire est de définir une adresse de méthode sur commande. Quelque chose comme ceci:
Et vous pouvez accéder à des utilisateurs d'adresse au moment de l'achèvement de la commande avec
@order.address
revision_at
est une méthode ajoutée à un vérifiés par le modèle acts_as_audited. Il prend un horodatage et reconstruit le modèle comme il l'était à ce point de temps. Je crois que c'pièces de la révision ensemble des audits sur ce modèle spécifique avant le moment donné. Donc, il n'a pas d'importance si updated_at sur le bon de commande correspond à un temps exactement.Je pense que cela pourrait être aussi simple que:
Ensuite, lorsqu'un utilisateur modifie son adresse, à vous de faire une sorte de "logique de supprimer" sur les anciennes données par la création d'une nouvelle UserAddress, et la définition de la "previous_address_id" sur le terrain pour être le pointeur vers les données anciennes. Ceci élimine le besoin pour votre plan de table, et crée une sorte de liste liée. De cette façon, chaque fois qu'une commande est passée, vous l'associez à un particulier UserAddress qui est garanti de ne jamais changer.
Un autre avantage de cela est qu'il vous permet de suivre les modifications d'un utilisateur, comme une sorte de rudimentaire enregistreur.