这让我一整天都感到沮丧。
我正在尝试从位于非典型位置的模块.rb文件扩展我的模型。在我的模型中,我尝试基于模型中的属性扩展到模块。模型被传递给View,我希望View在所有情况下都调用相同的Module方法(“content”),而不管Model的路径属性如何。
Test < ActiveRecord::Base
...
after_initialization do |test|
if !self.path.nil?
if File.exists?('app/views/' + self.path + '/_extend.rb')
extend 'app/views/' + self.path + '/_extend'
end
end
end
...
end
尝试从其他文件动态添加类方法。我想尝试让事情井然有序,这就是为什么我想把所有的模块方法都填入模型中并带有一个巨大的开关盒。
有什么建议吗?感谢。
答案 0 :(得分:2)
ruby的extend
方法不适用于路径。您需要提供要扩展的模块。因此,您不应存储path
,而应存储某种type
,以后可以使用它来获取对要扩展的模块的引用。一个小例子:
module GuestBehavior
def has_access?
false
end
end
module AdminBehavior
def has_access?
true
end
end
class User < ActiveRecord::Base
after_initialize :extend_behavior
def extend_behavior
return if kind.blank?
behavior_module = "#{kind.capitalize}Behavior".constantize
extend behavior_module
end
end
admin = User.new(:kind => 'admin')
guest = User.new(:kind => 'guest')
admin.has_access? # => true
guest.has_access? # => false
这是一个实验,而不是我实际编写的代码。它应该让你知道如何实现你的目标。
编辑:如果您想将模块放在不同的位置,您可以轻松地将其运行。假设您使用rails,则有自动加载器。当您访问未定义的常量时,自动加载器会启动并尝试加载文件,该文件定义了该constat。上面的例子看起来像:
app/models/guest_behavior.rb
app/models/admin_behavior.rb
您无需在代码中添加任何require
语句。当您访问GuestBehavior
或AdminBehavior
时,Rails会自动加载文件。 (这就是constantize
调用的内容)