如何为rails问题添加特定于模型的配置选项?
我正在为我的rails项目编写一个可导入的问题。 这个问题将为我提供一种将csv文件导入任何包含Importable的模型的通用方法。
我需要一种方法让每个模型指定导入代码应该使用哪个字段来查找现有记录。 是否有任何建议的方法可以为关注点添加此类配置?
我建议创建一个ActiveRecord
子模块并使用它扩展ActiveRecord::Base
,然后在该子模块中添加一个方法(比如include_importable
),而不是在每个模型中包含关注点。 然后,您可以将字段名称作为参数传递给该方法,并在该方法中定义实例变量和访问器(例如importable_field
)以保存字段名称,以便在Importable
类和实例方法中进行引用。
所以这样的事情:
module Importable extend ActiveSupport::Concern module ActiveRecord def include_importable(field_name) # create a reader on the class to access the field name class << self; attr_reader :importable_field; end @importable_field = field_name.to_s include Importable # do any other setup end end module ClassMethods # reference field name as self.importable_field end module InstanceMethods # reference field name as self.class.importable_field end end
然后,您需要使用此模块扩展ActiveRecord
,例如将此行放在初始化程序中( config/initializers/active_record.rb
):
ActiveRecord::Base.extend(Importable::ActiveRecord)
(如果问题出在你的config.autoload_paths
那么你不需要在这里要求它,请参阅下面的评论。)
然后在您的模型中,您将包括像这样的Importable
:
class MyModel include_importable 'some_field' end
而且imported_field
阅读器将返回该字段的名称:
MyModel.imported_field #=> 'some_field'
在InstanceMethods
,您可以通过将字段名称传递给read_attribute
来设置实例方法中导入字段的值,并使用read_attribute
获取值:
m = MyModel.new m.write_attribute(m.class.imported_field, "some value") m.some_field #=> "some value" m.read_attribute(m.class.importable_field) #=> "some value"
希望有所帮助。 这只是我对此的个人看法,但还有其他方法可以做到(我也有兴趣了解它们)。
一个稍微“看起来像香草”的解决方案,我们这样做(巧合的是,对于一些csv导入问题),以避免将参数传递给Concern。 我确信错误提升抽象方法有利有弊,但它会将所有代码保存在app文件夹中以及您希望找到它的模型中。
在“关注”模块中,只是基础知识:
module CsvImportable extend ActiveSupport::Concern # concern methods, perhaps one that calls # some_method_that_differs_by_target_class() ... def some_method_that_differs_by_target_class() raise 'you must implement this in the target class' end end
在有关注的模型中:
class Exemption < ActiveRecord::Base include CsvImportable # ... private def some_method_that_differs_by_target_class # real implementation here end end