1

这让我每天有 1/2 感到沮丧。

我正在尝试从位于非典型位置的模块 .rb 文件扩展我的模型。在我的模型中,我尝试根据模型中的属性扩展到模块。模型被传递给视图,并且我希望视图在所有情况下都调用相同的模块方法(“内容”),而不管模型的路径属性如何。

 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

只是尝试从不同的文件动态添加类方法。我想尝试让事情井井有条,这就是为什么我想用一个巨大的开关盒将我所有的模块方法填充到模型中。

有什么建议么?谢谢。

4

1 回答 1

2

ruby 的extend方法不适用于路径。您需要提供要扩展的模块。因此,您不应该存储 a 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

这更像是一个实验,而不是我实际编写的代码。它应该让你知道如何实现你的目标。

编辑:如果你想把模块放在不同的地方,你可以很容易地让它工作。假设您使用导轨,则有自动加载器。当您访问未定义的常量时,自动加载器会启动并尝试加载定义该常量的文件。上面的示例可能类似于:

app/models/guest_behavior.rb
app/models/admin_behavior.rb

您无需require在代码中添加任何语句。GuestBehaviorRails 会在你访问或时自动加载文件AdminBehavior。(这就是constantize电话的作用)

于 2013-01-06T00:53:52.713 回答