想要使用ActiveRecord模型开发rubygem

时间:2018-07-27 17:02:25

标签: ruby-on-rails activerecord rubygems ruby-on-rails-5

我想开发一个rubygem,该宝石打算安装在rails应用程序中。

gem将包含少量模型及其数据库迁移。

我还想添加断言模型及其关系的测试。我更喜欢RSpec。

在我即将开始的时候,我遇到了一个问题,即如何在gem中使用ActivRecord,以便通过测试可以插入固定数据并测试关系和行为。我相信SQLite应该被证明是最好的数据库选项。

注意:我之前没有开发过任何Rubygem,这将是我尝试的第一个。因此,将非常感谢您提供任何帮助,以指导我朝正确的方向发展。

谢谢。

2018年7月30日更新

我发现了一个类似的问题Ruby Gem Development - How to use ActiveRecord?,这正是我想要做的。但是答案并不十分清楚。希望这有助于理解我的问题。

1 个答案:

答案 0 :(得分:1)

您可以使用生成器获得所需的功能。基本上,您为用户应具有的文件(模型,迁移,测试)编写模板,并将其与gemfile保存在一起。然后,您允许用户使用命令复制这些文件。

This is a good link会详细介绍生成器,但这是我在其中的一个宝石中使用的一个小示例:

gem_name / lib / generators / gem_name / install_generator.rb

module GemName
  class InstallGenerator < Rails::Generators::Base
    include Rails::Generators::Migration

    # Allow user to specify a different model name
    argument :user_class, type: :string, default: "User"

    # Templates to copy
    source_root File.expand_path('../../../templates', __FILE__)

    # Copy initializer into user app
    def copy_initializer
      copy_file('create_initializer.rb', 'config/initializers/gem_name.rb')
    end

    # Copy user information (model & Migrations) into user app
    def create_user_model
      fname = "app/models/#{user_class.underscore}.rb"
      unless File.exist?(File.join(destination_root, fname))
        template("user_model.rb", fname)
      else
        say_status('skipped', "Model #{user_class.underscore} already exists")
      end
    end

    # Copy migrations
    def copy_migrations
      if self.class.migration_exists?('db/migrate', "create_gem_name_#{user_class.underscore}")
        say_status('skipped', "Migration create_gem_name_#{user_class.underscore} already exists")
      else
        migration_template('create_gem_name_users.rb.erb', "db/migrate/create_gem_name_#{user_class.pluralize.underscore}.rb")
      end
    end

    private

    # Use to assign migration time otherwise generator will error
    def self.next_migration_number(dir)
      Time.now.utc.strftime("%Y%m%d%H%M%S")
    end
  end
end

最后,只是一些建议/个人意见;您的gem应该在各种测试套件和数据库下运行,否则应表明您仅支持该设置,并假定它们在用户项目中可用。尽管我认为您可以在第二个测试套件中试一下,但是尝试强制建立第二个数据库是不可能的,而且您也不必担心数据库会使用迁移,除非您想要使用不可用的数据类型在所有受支持的数据库中。

我认为,更好的方法是为所需的规范编写单独的生成器,并让用户可选地运行它们。这会将测试复制到其中,并允许他们根据需要进行修改。