我很确定我在这里遗漏了一个基本错误,所以我希望另一双眼睛可能会有所帮助。我正在使用 Rails 3、Ruby 1.9.2 和 Rspec 2。
我想在模型上定义动态类方法,以便在将可分配对象(例如帐户)添加到系统时返回它们的基本角色。例如:
BaseRole.creator_for_account
通过控制台一切正常:
ruby-1.9.2-p180 :003 > BaseRole.respond_to?(:creator_for_account)
=> true
但是当我为任何类方法运行我的规范时,无论我在规范中调用该方法,我都会得到一个NoMethodError
。我假设我如何动态声明这些方法的某些内容与 RSpec 无关,但我似乎无法弄清楚原因。
lib dir 是自动加载的路径,方法对 respond_to?返回 true。
# /lib/assignable_base_role.rb
module AssignableBaseRole
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
BaseRole.all.each do |base_role|
role_type = RoleType.find(base_role.role_type_id)
assignable_name = base_role.assignable_type.downcase
method = "#{role_type.name}_for_#{assignable_name}"
define_method(method) do
self.where(:role_type_id => role_type.id,
:assignable_type => assignable_name).first
end
end
end
end
然后将模块包含在基本角色中
# /models/base_role.rb
class BaseRole < ActiveRecord::Base
include AssignableBaseRole
belongs_to :role
belongs_to :role_type
......
......
end
然后在我的规范中:
it "adds correct authority for creator role" do
create_assignment
base_role = BaseRole.creator_for_account # <== NoMethodError here
user1 = Factory.create(:user)
account.users << user1
user1.roles_for_assignable(account).should include(base_role.role)
end
您的项目或规范中是否有另一个同名的类,但没有添加动态方法?我遇到了与您完全相同的问题,重命名其中一个类可以解决它。
我的猜测是另一个类首先加载
您似乎正在根据数据库中的值定义这些方法:
BaseRole.all.each do |base_role|
.....
可能是"创建者"作为角色类型在测试数据库中不存在,或者"帐户"作为assignable_type不存在?
据推测,您是在控制台中对此进行测试以进行开发,而不是测试,因此数据可能不匹配。可能需要在 beforehook 中设置数据。