2011-05-16 60 views
4

我很确定我错过了一个基本的错误,所以我希望另一组眼睛可能会有所帮助。我正在使用Rails 3,Ruby 1.9.2和Rspec 2.RSpec中的动态define_method抛出错误

我想在模型上定义动态类方法,以便在添加到可分配对象(如帐户)时返回基本角色系统。例如:

BaseRole.creator_for_account 

一切通过控制台正常工作:

ruby-1.9.2-p180 :003 > BaseRole.respond_to?(:creator_for_account) 
=> true 

但是当我跑我的规格对于任何类的方法,我得到一个NoMethodError无论我呼吁在规范的方法。我假设我是如何动态声明方法的东西不是用RSpec拼凑出来的,但我似乎无法弄清楚为什么。

lib目录是自动加载路径,并且这些方法对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 

然后包括在BaseRole

# /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 
+0

如果您删除模块,它仍然是一个问题?我也在类文件中使用define_method来获得这个,只有在guard后面使用rspec。 – 2013-11-23 05:37:29

回答

0

看样子你是基于数据库值定义这些方法:

BaseRole.all.each do |base_role| 
..... 

难道是“crea tor“作为角色类型不存在于测试数据库中,或者”account“不存在作为assignable_type?

大概你是在控制台上测试这个进行开发,而不是测试,所以数据可能不匹配。可能需要在挂钩之前设置数据。

+0

感谢您的回复,我确实验证了测试数据的存在。我正在通过数据库加载数据,并且正在开发中使用控制台,主要是为了看看是否会定义方法,因为RSpec中有些奇怪。但是你可能会用前面的书和/或以某种方式预加载数据。这可能是不同的东西如何加载和/或当我玩控制台与测试环境。 – 2011-05-16 22:18:31

+0

很酷。有兴趣听听你的发现。 – twmills 2011-05-17 18:25:00

1

您的项目中是否有另一个类或具有相同名称的规格,但没有添加动态方法?我和你有完全相同的问题,并且重命名其中一个类修复了它。

我的猜测是其他类正在首先加载