我有一个客户端模型,在下面的实例变量中,我正在收集所有标识符。
@all_clients = Client.all.collect{|a| a.identifier}
这将返回["client123", "client234", "client567", "client789"]
此外,我有一个变量@create_id =“client123”,我正在通过@all_clients.include? @create_id
检查集合中是否存在@ create_id的值
如果返回true,我将像这样添加“_1”:@create_id<<"_1"
并保存@create_id
以后通过该ID创建客户端。
我再次检查集合中是否存在最新的@create_id
“client123_1”,如果是,我添加_2并进一步检查并最终保存。
这是我所知道的最糟糕的检查方式,因为我是编程新手。
有人可以帮助我找到一种有效的方法来做到这一点。
我需要做的就是首先检查我的变量是否为 如果不存在,则将_1附加到它,然后检查string_1是否为 已经存在并进一步向_2或_3进一步移动。该 下划线和整数保持增量取决于检查 集合。
提前致谢
答案 0 :(得分:2)
您可以将AR查询限制为仅包含与@create_id
clients=Client.arel_table
matching_clients = Client.where( clients[:identifier].matches( "#{@create_id}%" ) )
如果matching_clients
为空,则没有具有该标识符前缀的客户端。除此以外
现在你可以提取整数后缀片段并找出下一个可用的id是什么。
last_suffix = matching_clients.
map(&:identifier).
map { |s| (s.split('_',2)[1] || 0).to_i }.
max
如果索引支持标识符字段,则应该相当有效。
如果你的方案使用了一个后缀格式,允许对后缀进行正确的词法排序(例如,总是将后缀填充到固定的宽度),那么你可以通过索引将更多的工作推送到数据库中。为匹配的最大标识符。
请注意,如果您有多个并发进程可能需要创建新的唯一标识符,则整个方法都会受到竞争条件的影响。如果您的db模式在clients.identifier
上具有唯一索引(它也支持查询效率),那么当您尝试使用您制造的新标识符保存记录时,db将抛出唯一性约束错误,在这种情况下,您可以继续尝试,重新选择并推导新的候选标识符,直到你再次成功。