باستخدام ActiveRecord, هل هناك طريقة للحصول على القيم القديمة من سجل خلال after_update
-
03-07-2019 - |
سؤال
الإعداد باستخدام مثال بسيط: لقد حصلت على 1 الجدول (Totals
) الذي يحمل مجموع amount
عمود من كل سجل في الجدول الثاني (Things
).
عندما thing.amount
يحصل على تحديث أود ببساطة إضافة الفرق بين القيمة القديمة و الجديدة القيمة total.sum
.
الآن أنا طرح self.amount
خلال before_update
وإضافة self.amount
خلال after_update
.وهذا يضع الكثير من الثقة في التحديث النجاح.
القيد: أنا لا أريد ببساطة حساب مجموع جميع المعاملات.
السؤال: ببساطة أود أن الوصول إلى القيمة الأصلية خلال after_update
رد.ما هي الطرق التي يجب علينا فعل هذا ؟
تحديث: أنا ذاهب مع لوقا Francl فكرة.خلال after_update
رد لا يزال لديك الوصول إلى self.attr_was
القيم التي هو بالضبط ما أردت.كما أنني قررت أن أذهب مع after_update
تنفيذ لأنني أريد الحفاظ على هذا النوع من المنطق في النموذج.بهذه الطريقة, لا يهم كيف قررت تحديث الصفقات في المستقبل ، سوف تعرف أنني تحديث مجموع المعاملات بشكل صحيح.شكرا للجميع الخاص بك تنفيذ الاقتراحات.
المحلول
كما سبق ما كل شخص يقول عن المعاملات.
إلى أن قال...
ActiveRecord من القضبان 2.1 بتتبع قيم السمة كائن.حتى إذا كان لديك سمة total
, سيكون لك total_changed?
طريقة total_was
طريقة إرجاع القيمة القديمة.
ليس هناك حاجة لإضافة أي شيء إلى النموذج الخاص بك لتتبع هذا بعد الآن.
تحديث: هنا هو وثائق ActiveModel::القذر على النحو المطلوب.
نصائح أخرى
بعض الناس بالذكر التفاف كل هذا في الصفقة, ولكن أعتقد أن يتم ذلك بالنسبة لك ؛ تحتاج فقط لتحريك الاستعادة من خلال رفع استثناء أخطاء في after_* رد.
انظر http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
كامل الاستدعاء سلسلة من إنقاذ, إنقاذ!, أو تدمير دعوة يعمل ضمن الصفقة.يتضمن after_* السنانير.إذا كان كل شيء يسير على ما يرام ارتكاب يتم تنفيذه مرة واحدة السلسلة قد اكتملت.
إذا before_* رد يلغي العمل التراجع صدر.يمكنك أيضا تحريك التراجع رفع استثناء في أي من الاسترجاعات ، بما في ذلك after_* السنانير.نلاحظ أن في هذه الحالة يجب على العميل أن يكون على علم به لأن العاديين لإنقاذ رفع هذا الاستثناء بدلا من العودة بهدوء كاذبة.
إلحاق "_was" إلى السمة الخاصة بك سوف تعطيك القيمة السابقة قبل حفظ البيانات.
هذه الأساليب تسمى الأساليب القذرة الأساليب.
هتاف!
للحصول على تغير كل المجالات ، مع القديم والجديد القيم على التوالي:
person = Person.create!(:name => 'Bill')
person.name = 'Bob'
person.save
person.changes # => {"name" => ["Bill", "Bob"]}
ActiveRecord::القذر هو وحدة الذي بني في ActiveRecord لتتبع سمة التغييرات.بحيث يمكنك استخدام thing.amount_was
للحصول على القيمة القديمة.
هذا إضافة إلى النموذج الخاص بك:
def amount=(new_value)
@old_amount = read_attribute(:amount)
write_attribute(:amount,new_value)
end
ثم استخدام @old_amount في after_update رمز.
أولا, يجب عليك أن تفعل هذا في الصفقة لضمان أن يحصل على البيانات الخاصة بك مكتوبة معا.
للإجابة على السؤال الخاص بك ، يمكنك فقط تعيين عضو متغير القيمة القديمة في before_update ، والتي يمكنك ثم الوصول في after_update, لكن هذا ليس حل أنيقة جدا.
فكرة 1:التفاف التحديث في قاعدة البيانات الصفقة ، بحيث إذا فشل تحديث المجاميع الخاصة بك الجدول لا يتغير: ActiveRecord المعاملات مستندات
فكرة 2:خبأ القيمة القديمة في @old_total خلال before_update.