ruby - 如何在 Ruby 中动态创建类方法?
问题描述
在 Rails 中,我们可以调用“Person.find_by_attribute”,其中“attribute”由“Person”迁移中的属性动态放置。我想在没有导轨的 Person 类中复制这个逻辑,并为属性调用“find_by_attribute”。到目前为止我所拥有的:
class Person
def attributes
[
{ id: 1, nice_attribute: "something" },
{ id: 2, nice_attribute: "another thing" },
]
end
def find_by_id(id)
attributes.select { |d| d[:id] == id }
end
但是像这样定义 find_by 可能会使类很快膨胀。如何实现动态def设置?
解决方案
我有理由确定这不是这样Rails
做的,但这里有一些可能对您有所帮助的实现:
您在那里定义的是一个Singleton
类,在提交该设计之前,您应该知道如何在此类中动态定义属性记录。这可能是一个不错的选择,但您应该为该类提供一个访问点,以搜索在其他地方定义的记录。无论如何,以下内容将帮助您入门:
class Person
@@attributes = { id: Integer, nice_attribute: String }
# getter method
def self.attribute_types
@@attributes
end
attribute_types.keys.each do |attr|
define_singleton_method :"find_by_#{attr}" do |value|
# logic
end
end
end
然后你就可以打电话Person.find_by_id
或Person.find_by_nice_attribute
当您实现时,拥有一个PersonRecord
从数据库收集记录的模块可能会更好,并且Person
该类可能是这样的实例:
class Person
def initialise(opts ={})
define_find_by_methods
end
def attribute_keys
# stub method, but should be collecting this information dynamically
[ :id, :nice_attribute ]
end
def define_find_by_methods
attribute_keys.each do |attr|
# no longer using define_singleton_method here and define_method is a class method you will have to send it to self.class
self.class.send(:define_method, :"find_by_#{attr}") do |val|
# logic
end
end
end
end
推荐阅读
- excel - 我得到一个#Name?运行宏时出错
- html - 部分出现在 html 中的正常流程之外
- mercurial - 分支上的新远程头?水银推送错误
- c# - Csv 文件被读入我的 ReadCsvFile 方法,但没有被传递到我解析它的位置(TinyCsvParser)
- java - 在 java 中使用元数据转换 JPEG 文件名
- php - 如何修复 Laravel/Lumen 应用程序中的“cURL 错误 6:无法解析主机”
- reactjs - Google API 与来自 `react-router` v3 的 `Link` 一起使用时似乎会导致某种错误
- unity3d - 漂浮在 RWTexture
根据 if 语句的哪一侧输出不一致的值 - redis - Redis Streams 如何处理耗尽所有可用内存的问题?
- mysql - 请求 SQL:加入表并且不想要多个值