باستخدام ActiveRecord, هل هناك طريقة للحصول على القيم القديمة من سجل خلال after_update

StackOverflow https://stackoverflow.com/questions/607069

سؤال

الإعداد باستخدام مثال بسيط: لقد حصلت على 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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top