سؤال

أنا أحصل على إجهاض! ... posts_count تم وضع علامة على أخطاء readonly.

لدي نموذجان: المستخدم والنشر.

users has_many posts.

posts belongs_to :user, :counter_cache => true

لديّ ترحيل يضيف عمود posts_count إلى جدول المستخدمين ثم يحسب ويسجل العدد الحالي من المنشورات لكل مستخدم.

self.up
  add_column :users, :posts_count, :integer, :default => 0

  User.reset_column_information
  User.all.each do |u|
    u.update_attribute( :posts_count, u.posts.count)
  end
end

عندما أقوم بتشغيل الترحيل أحصل على الخطأ. هذا واضح إلى حد ما ، بالطبع ، وإذا قمت بإزالة إعلان: counter_cache من نموذج المنشورات ، على سبيل المثال

belongs_to :user

الهجرة تعمل بشكل جيد. من الواضح أن هذا ليس منطقيًا لأنك لا تستطيع تنفيذها بهذه الطريقة حقًا. ماذا ينقصني؟

هل كانت مفيدة؟

المحلول

يجب أن تستخدم User.reset_counters لفعل هذا. بالإضافة إلى ذلك ، أوصي باستخدام find_each بدلاً من each لأنها ستكرر المجموعة على دفعات بدلاً من كل مرة.

self.up
  add_column :users, :posts_count, :integer, :default => 0

  User.reset_column_information
  User.find_each do |u|
    User.reset_counters u.id, :posts
  end
end

نصائح أخرى

حسنًا ، تنص الوثائق على:

تتم إضافة أعمدة ذاكرة التخزين المؤقت المضادة إلى قائمة السمات القراءة فقط من خلال attr_readonly.

أعتقد أن هذا ما يحدث: أنت تعلن العداد في تعريف النموذج ، مما يجعل سمة "posts_count" للقراءة فقط. ثم ، في الترحيل ، تحاول تحديثه مباشرة ، مما يؤدي إلى الخطأ الذي ذكرته.

يتمثل الحل السريع في إزالة إعلان counter_cache من النموذج ، وتشغيل الترحيل (من أجل إضافة العمود المطلوب إلى قاعدة البيانات وملبئه مع تعدادات المنشور الحالية) ، ثم إعادة إضافة إعلان counter_cache إلى الموديل. يجب أن تعمل ولكنها سيئة وتتطلب تدخلًا يدويًا أثناء الهجرة - ليست فكرة جيدة.

وجدت منشور المدونة هذا وهو ما يشير إلى تغيير قائمة السمات القراءة فقط أثناء الترحيل ، فهي مغمورة بعض الشيء ولكن قد ترغب في تجربتها.

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