我正在尝试使用一组简单的ruby对象模仿ActiveRecord来运行原始sql查询。以下是我一直在试验的峰值:
module Runable
def run
return self::Results.new
end
end
module Query
class Results
def initialize
@results = Object.find_by_sql()
end
def to_a
#code
end
end
end
module Scored
extend Runable
include Query
QUERY = 'a raw sql query string'
end
module Unseen
extend Runable
include Query
QUERY = 'a different raw sql query string'
end
我希望能够为我将要运行的每种原始sql查询创建简单的模块,将它们放入上面的Scored
或Unseen
等文件中并调用{ {1}}在他们身上找回结果对象。像这样:
.run
但我得到了这个......
Scored.run #=> #<Scored::Results:0x0000000000>
Unseen.run #=> #<Unseen::Results:0x0000000000>
我一直在做红宝石和铁轨超过一年但我刚刚开始使用更高级的红宝石用法。这是我使用模块和mixins的第一步。
据我所知,问题是模块类方法的自定义范围是它们定义的模块。所以我得到Scored.run #=> #<Query::Results:0x0000000000>
Unseen.run #=> #<Query::Results:0x0000000000>
因为结果的initialize方法在Query模块中定义。这有道理吗?
感谢您的帮助!
更新5/30 16:45
基本上,我想将一些原始SQL语句包装到这样的模块中:
Query::Results
并与这样的查询互动:
module ScoredUsers
include Queryable
QUERY="SELECT * FROM users ..."
end
我希望将所有内容保存在模块和类中,这是红宝石的方式(我认为?)所以当我想创建一个新的查询对象时,我可以简单地使用上面的r = ScoredUsers.run #=> ScoredUsers::Results
r.ids
r.load_objects
REDIS.zadd user:5:cache, r.to_a
这样的样板模块。
答案 0 :(得分:1)
您获得此类结果的原因是类Results
只创建一次。当包含模块时,在包含类(Scored::Results
)的内部创建新常量,但它指向与常量Query::Results
相同的内存空间。
你需要的是你必须为这个模块所包含的每个类创建一个新类。这是使用included
方法的绝佳机会:
module Query
def self.included(mod)
results = Class.new do
def initialize
@results = Object.find_by_sql()
end
def to_a
#code
end
end
mod.const_set('Results', results)
end
end
现在我们当然还有问题 - 我们真的需要这样做吗?这取决于您计划如何使用这些类。