想实现一个像 rails 中 scope 这样的功能,自己定义的函数可以连接起来调用。代码如下:
# class My_string
# attr_accessor :m_string
# def initialize(string)
# self.m_string = string
# end
# def part(b,e)
# m_string[b,e]
# self
# end
# def limit(length)
# m_string[0..length]
# self
# end
# end
# s = My_string.new("hello world")
# s.part(1,5).limit(3) ##返回结果为对象,不是所希望的结果
在Rails中,用Scope定义了3个函数,假设分别为A,B, C
然后我们就可以这样使用Model.A.B.C;也可单独使用,比如
Model.A
Model.B
Model.C
Model.A.B.C这样的函数链的调用是怎么实现的,谁能讲下原理,或者简单的写段代码阐述一下也可以?
求高手指点?
#5 楼 @jjym 我只是用字符串举个例子,我的目的是把自定义的函数连起来调用,测试中也有很多这样的用法,比如:
describe "responding to GET index" do
it "should expose all comms as @comms" do
Comm.should_receive(:find).with(:all).and_return([mock_comm])
get :index
assigns[:comms].should == [mock_comm]
end
# ...
Comm.should_receive(:find).with(:all).and_return([mock_comm]) 这样是怎么实现的?
class String
def part(b ,e)
String.new self[b, e]
end
def limit(length)
String.new self[0 .. length]
end
end
s = "Hell, world!"
puts s.part(1 ,5).limit(3)
class MyString < String
def part(b ,e)
MyString.new self[b, e]
end
def limit(length)
MyString.new self[0 .. length]
end
end
s = MyString.new "Hell, world!"
puts s.part(1 ,5).limit(3)
#6 楼 @zhenjunluo 我看不明白这段代码的意思 反正返回的不是 self,就是一个新对象。所以如果想返回字符串,那就让返回的对象是 String 类或者子类
#12 楼 @zhenjunluo 明白了。scope 就是动态定义一个方法,这个方法先执行 lambda 的操作,然后返回 self,于是就可以链式调用了。最后也是要用 all/count 之类的方法来获得计算结果或者内部状态的。我不熟 ruby,不知道要怎么写
http://asciicasts.com/episodes/239-activerecord-relation-walkthrough 这里有讲到 Rails 中 Relation 的实现
http://stackoverflow.com/questions/5844598/what-is-an-activerecord-rails-relation-really stackoverflow 上面相关的一个问题
链式调用的原理就是返回 self,这点没错。Rails 的 scope 也不例外。说两点:
会不会是这样:模型上调用 scope 方法,返回的就是一个关系对象,同时模型会成为关系对象的代理,模型的某个实例变量也会保存这个 scope 的查询条件;如果在关系对象是调用 scope 方法,依然返回 scope;否则,就调用它的代理的对应方法(也就是模型的方法,可以指定特定方法或者在关系对象的 method_missing 中捕捉),这些方法会用到那些查询条件。
看了 rails2 中的 named_scope,似乎是用的上面的方法。不过有些地方没看懂,仅供参考。