将.rb文件列表存储在模型

时间:2016-02-05 15:36:03

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 ruby-on-rails-3.2 rails-activerecord

同事!我有文档模型。文档应该由其中一个解析器处理(在我的项目中,它们被称为'importers'并存储在'lib / importers'文件夹中)。问题是在模型层中实现实体Importer的最佳方法是什么? (例如与进口商关联的文件)。

  1. 首先想法是创建导入器表,但是我将有2个独立的位置,其中将保存导入器名称(数据库和文件系统)。不好的情况:
  2. 案例1:我已经批准了一个新的导入程序,但忘记将其添加到导入程序表中=我无法将文档与此impoter关联

    案例2:导入程序已重命名,我们忘记将其重命名为database = error

    1. 我决定定义

      def Document.importers @importers ||= Dir.entries("#{Rails.root}/lib/importers/") .select { |name| !File.directory?(name) && name != 'base_importer.rb'} .map { |name| name.gsub(/\.rb$/, '') } end

    2. 用于f.association inout并将importer字符串属性添加到文档模型。所以我可以通过以下方式获得导入器类 - 'importer.classify.constantize'。它有效,但看起来令人毛骨悚然

      你能为这种情况建议更好的解决方案吗?我将很高兴听到任何想法;)

2 个答案:

答案 0 :(得分:0)

我会在数据库中对它们进行建模,然后在文件发生变化时使用一些系统来更新数据库。这种情况一直发生在资产管理系统中:您有一些物理文件和一些数据,是的,如果它们不同步,您就会遇到问题。因此,您将系统放置到位以尝试使它们保持同步。你可以有一个rake任务来根据物理文件更新数据库,例如,协议就是你需要在更改文件后运行rake任务,如果你没有,那么你搞砸了问题是你的错。开发人员应该能够在这些规则中工作。

最终,Rails是关于对象关系数据的,所以如果你想使用rails,请使用它。如果你每次都尝试按照文件夹的内容来实时构建大量实例,那么你最终会得到一个非常复杂和低效的系统。

答案 1 :(得分:0)

在当地的红宝石聊天中,在脑风暴期间进行了解决:

我没有提到所有导入器都是从base_importer继承的,而base_importer也放在lib / importers中。我们决定在其中添加'inheritors'数组,并使用ruby核心提供的hook' inherited'存储所有的继承者 - > http://ruby-doc.org/core-2.2.0/Class.html#method-i-inherited

class BaseImporter
  @inheritors = []

  def self.inheritors
    @inheritors
  end

  def self.inherited(subclass)
    @inheritors << subclass.name
  end
  # ...
end

我们期望它运行良好,但我们忘了,所有类都在Rails中加载。所以BaseImporter.inheritors会在新系统启动时将[]返回给你。

anton@anton:~/Projects/project$ rails c
Running via Spring preloader in process 16832
Loading development environment (Rails 4.2.5)
B2.2.3 :001 > BaseImporter.inheritors
 => [] 

为了强制加载所有进口商,我制作了初始化程序:

# config/initializers/importers.rb
# Preload importers
require 'base_importer'
Dir.glob("#{Rails.root}/lib/importers/*.rb").each { |file| require file }

首先应该加载BaseImporter,因为如果在BaseImporter之前加载任何导入器它将不会触发'inherited'hook:

anton@anton:~/Projects/project$ rails c
Running via Spring preloader in process 16846
Loading development environment (Rails 4.2.5)
2.2.3 :001 > require "xxx_importer"
 => true 
2.2.3 :002 > require "base_importer"
 => true 
2.2.3 :003 > require "yyy_importer"
 => true 
2.2.3 :004 > BaseImporter.inheritors
 => ["XxxImporter"] 

随时发布您对此解决方案的反馈意见。我很乐意听到它