我正在尝试构建一个休息客户端,因为很多事情几乎相同,我认为我将这些操作放入模块中,只是扩展模块以获取该组操作并保持通过将它们定义为常量,相同的常量来分隔唯一的位,但每条路径的设置都不同,因此最终结果是不同的URL,但操作相同。
module Common
def list
"some_url/#{Route_Name}.json"
end
end
class Posts
extend Common
Route_Name = 'posts'
end
class Comments
extend Common
Route_Name = 'comments'
end
Comments.list
#=> "some_url/comments.json" what I expect to be outputted
但它只是错误,在这个例子中它会错误uninitialized constant Common::Route_Name
。
如何让Route_Name
成为我期望的目标?
编辑:
我通过将Route_Name
更改为@route_name
来解决了这个问题,但问题是Route_Name
是不变的,它永远不会改变,所以感觉不对实例变量,即使它确实有效。
答案 0 :(得分:2)
Ruby does constant lookup首先是命名空间(粗略地说:你已经嵌套了它们),然后是祖先(你从中继承过的)。由于在list
中声明Common
,因此查询以Common::Route_Name
开头,无法继续查询。
但是,当list
被调用时,它会在Comments
或Posts
上被调用,让您通过self
访问这些内容。您可以使用self::Route_Name
在您想要的地方进行查找,而不是让Ruby自己查找常量。
module Common
def list
"some_url/#{self::Route_Name}.json"
end
end
class Posts
extend Common
Route_Name = 'posts'
end
class Comments
extend Common
Route_Name = 'comments'
end
puts Comments.list #=> some_url/comments.json
puts Posts.list #=> some_url/posts.json
答案 1 :(得分:1)
我做过类似的事情,我在模块中定义了几个控制器动作(索引,创建等等),然后在控制器中只有include MyModule
想要使用它们。
此时,在我的模块中,我可以致电self.controller_name
以获取我实际来自的地方。
因此,您可以使用Route_Name
或self.controller_name.tableize
self.class.tableize
,而不是尝试设置setBackgroundDrawable()
。
答案 2 :(得分:1)
请改用@@route_name
。这是一个方法调用(与静态名称查找相比)。这意味着,它将从祖先层次结构的底部开始持续查找。
const_get
@mtamhankar关于从类名派生路线有一个很好的观点。也许是这样的(使用ActiveSupport中的module Common
def list
"some_url/#{const_get('Route_Name')}.json"
end
end
class Posts
extend Common
Route_Name = 'posts'
end
class Comments
extend Common
Route_Name = 'comments'
end
Comments.list # => "some_url/comments.json"
)
tableize
答案 3 :(得分:0)
-ExpandProperty
是一个实例变量并且可以工作,但我认为你实际需要的是@route_name
,它会使它成为一个类级变量(每个类一个,而不是每个实例)。
答案 4 :(得分:0)
ruby方法从该方法的owner
中查找常量,而不是接收器或接收器的类。当您访问常量时,ruby解释器会在调用模块或类的Module.nesting
中查找常量。
X = 0
module A
X = 1
module B
p Module.nesting #=> [A::B, A]
X = 2
def self.x
X
end
end
end
A::B.x # Try commenting out any 'X = ?' to see the difference
当您调用A::B.x
时,ruby会尝试在命名空间X
中找到常量A::B
(即尝试查找A::B::X
),如果找到,则会停止查找并立即返回该值。如果找不到,那么ruby会尝试在X
内找到A
,如果仍然不是fount,则ruby会尝试在顶级命名空间中找到X
,即Object
。< / p>
由于类和模块有一个类/模块方法name
,它返回类/模块的名称,你可以像这样重构Common
模块:
module Common
def list
"some_url/#{name.downcase}.json"
end
end
并消灭所有Route_Name = 'xxx'