1

我有一个模块,它定义了一个类方法来根据给定列中的值动态定义一系列实例方法,大致如下:

lib/active_record_extension.rb

module ActiveRecordExtension
  extend ActiveSupport::Concern

  module ClassMethods
    def define_some_methods(*attribute_names)
      # define some methods
    end
  end
end

ActiveRecord::Base.send(:include, ActiveRecordExtension)

config/initializers/extensions.rb

require 'active_record_extension.rb'

应用程序/模型/my_model.rb

class MyModel < ActiveRecord::Base
  define_some_methods :first_attribute, :second_attribute
end

将类方法添加到 ActiveRecord::Base 的设置基于此问题的第一个答案。

这在我的 Rails 应用程序和控制台中运行良好,允许我定义各种类似的方法而不会弄乱我的模型。但是,它在我的 rspec 测试中根本不起作用,现在这些测试都以NoMethodErrors 失败,用于调用动态定义的方法。

在运行 rspec 时,如何确保此模块(或仅此方法)正确包含在我的模型中?

编辑:这是我的spec/spec_helper.rb

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'

#to test with sunspot
require 'sunspot/rails/spec_helper'
RSpec.configure do |config|
  ::Sunspot.session = ::Sunspot::Rails::StubSessionProxy.new(::Sunspot.session)
end

#adds devise and jasmine fixture test helpers
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_base_class_for_anonymous_controllers = false
  config.order = "random"
end
4

1 回答 1

1

我会提出一种替代方法来解决第一个问题,它也应该解决您所询问的当前问题。ActiveSupport::Concern 在这里无法为您做任何 ruby​​ 做不到的事情,所以我会坚持使用纯 ruby​​ 并执行以下操作:

module ActiveRecordExtension
  def self.included(klass)
    klass.class_eval do 
      extend ClassMethods
    end
  end 
 module ClassMethods
  def define_some_methods(*attribute_names)
   # define some methods
  end
 end
end

ActiveRecord::Base.send(:include, ActiveRecordExtension)

如果您对包含的钩子有任何疑问,我可以更详细地解释。您也不需要在初始化程序中要求此文件(尽管进行更改时需要重新启动本地服务器)

于 2013-09-02T20:44:05.550 回答