inheritance被误解了

我正在尝试在我的应用程序中构建inheritance。

事实上,我很简单,我有几个模型,其中一些需要“归档”,它只是意味着我将数据从我的数据库公共原理图移动到归档原理图(相同的数据库)。

每个模型都有一个方法’save’itself’OnArchive示例:

def saveContactArchive(contact) record = ArchContacts.new record.id=contact.id record.information_id=contact.information_id record.is_internal = contact.is_internal if (contact.is_internal != nil) record.type_contact_id = contact.type_contact_id if (contact.type_contact_id != nil) record.user_id = contact.user_id if (contact.user_id != nil) record.info_readed = contact.info_readed if (contact.info_readed != nil) record.not_received = contact.not_received if (contact.not_received != nil) record.society_name = contact.society_name if (contact.society_name != nil) record.person_name = contact.person_name if (contact.person_name != nil) record.email = contact.email if (contact.email != nil) record.receipt = contact.receipt if (contact.receipt != nil) record.receipt_confirmed = contact.receipt_confirmed if (contact.receipt_confirmed != nil) record.created_at = contact.created_at if (contact.created_at != nil) record.updated_at = contact.updated_at if (contact.updated_at != nil) id = contact.id if (!existOnArchive(id)) return record.save else return true end end 

并且一些模型有一个例子save’arrayOf’OnArchive示例:

  def saveContactsArchive(contacts) resultContact = false for c in contacts if(c.id != nil) resultContact = saveContactArchive(c) else resultContact = true end if(!resultContact) ArchiveLogs.debug("Sauvegarde d'un contact sur l archive echoue, contact concerne "+c.inspect) end end return resultContact end 

我正在尝试为所有这些模型创建一个父类,称为Archive。 这个类定义了2个方法

  class Archive def saveOnArchive(element) "Save on archive" end def saveArrayOnArchive(elements) "Save an array on archive" end end 

saveArrayOnArchive对所有模型遵循相同的逻辑,例如saveContactsArchive; 循环数组,为每个元素调用saveOnArchive,如果错误则写入日志。

我的问题;

1)是否更好地创建模块化saveArrayOnArchive以及如何从父类调用children方法saveOnArchive?

2)我的模特会是什么样子? 他们要重新划分每种方法吗? 如果他们不向父方法添加任何内容,则调用super?

3)甚至是可能的,因为我的模型已经是来自activerecord类的子项.ArdenContacts <ActiveRecord :: Base —- EDIT —-为什么我的模型应该是ActiveRecord :: Base的子项(我只是跟着另一个开发模型没有大脑……)—-编辑—-

3 in 1)如果有人理解我,如何实现这一目标…任何帮助都是有帮助的

在你的情况下,它们似乎都具有相同的属性,因此你可以很好地利用方法#becomes ,它创建一个具有当前类相同属性的不同类的新实例,例如

 contact = Contact.first archived_contact = contact.becomes ArchContact archived_contact.save 

这将创建存档的联系人,并为您节省复制每个属性的所有麻烦。

首先让我解释一下方法调用是如何工作的,每个实例都有一个方法调用起泡的树,直到找到你要查找的方法为止,所以如果你调用saveOnArchive ,实例会查看它的类并检查是否有一个方法name,如果不是那么它会检查包含的模块,如果不是它检查类的SuperClass,那么SuperClass的模块,一直到树,然后落入method_missing方法,该方法打印错误,说明方法不是找到。

我不认为你有必要创建一个对象并且仅仅为2个方法提供它,你可以include一个具有这些方法的模块,例如这里是归档模块。

 module Archive ef method_1 end def method_2 end end 

然后将它包含在Contact类中

 class Contact < ActiveRecord::Base include Archive end 

现在你的Contact类有了method_1method_2因为它们存在于查找树中,但由于你在不同的表中有不同的类和每个存档,你可以添加一些动态方法来处理这个,这里有一个小例子

 module Archive def self.included(klass) klass.instance_eval do define_method "save_#{klass.name}_archive" do self.becomes "#{klass.name}Archive".constantize end end end end 

该模块使用包含它的类并获取其名称来定义动态方法,在这种情况下, contact模型将具有save_contact_archive方法,该方法返回填充了其属性的ContactArchive实例,然后您可以保存该对象。

但是如果名为User的类包含Archive模块,则这些方法将被称为save_user_archive并将其保存到名为save_user_archive的对象中。

一个简单的用法就是这样

 contact = Contact.first archived_contact = Contact.save_contact_archive archived_contact.save 

我希望我这么简单,如果你需要进一步的帮助请问。

您不能从多个类inheritance。 但是,您可以将此function放在模块中

 module Archivable extend ActiveSupport::Concern included do class_attribute :archive_class end def save_in_archive unless archive_exists? archive_class.create(attributes.reject {|_, value| value.nil?} end end #implement other methods such as archive_exists end 

你可以做课程

 class Contact include Archivable self.archive_class = ArchContacts 

结束

您可以执行以下操作:从模型名称推断存档类名称,或者将方法添加到包含模块并配置它的活动记录(如acts_as_list ),但基本方法是相同的。

我已经将您的方法更改为不逐个设置属性 – 如果没有,那么您将无法重用归档方法。 如果您不希望归档所有属性,那么我将添加另一个class_attribute,它可以是白名单或属性名称的黑名单,您可以使用切片attributes哈希。

您可能还会考虑设置ArchContacts.record_timestamps = false ,否则rails将更新您可能不想要的updated_atcreated_at列。