我想根据作为参数传递给方法的2D数组动态创建(可能很复杂)Active Record查询。换句话说,我想这样做:
arr = [
['join', :comments],
['where', :author => 'Bob']
]
并创建与此等效的内容:
Articles.join(:comments).where(:author => 'Bob')
一种方法是:
Articles.send(*arr[0]).send(*arr[1])
但是,如果arr
包含3个嵌套数组,或者4,或5,该怎么办?一种非常精致的方法是:
case arr.length
when 1
Articles.send(*arr[0])
when 2
Articles.send(*arr[0]).send(*arr[1])
when 3
Articles.send(*arr[0]).send(*arr[1]).send(*arr[2])
# etc.
end
但是是否有一种更简洁,更简洁的方式(不必多次访问数据库)?也许有一些方法可以在执行之前构造方法调用链?
答案 0 :(得分:2)
一种方便的方法是使用散列而不是2D数组。
类似这样的东西
my_subroutine.for:4:6:
subroutine uel(rhs, amatrx, svars, energy, ndofel, nrhs, nsvars,
1
Error: Bad continuation line at (1)
my_subroutine.for:4:6:
subroutine uel(rhs, amatrx, svars, energy, ndofel, nrhs, nsvars,
1
Error: Unclassifiable statement at (1)
my_subroutine.for:5:6:
1 props, nprops, coords, mcrd, nnode, u, du, v, a, jtype, time, dtime,
1
Error: Unclassifiable statement at (1)
my_subroutine.for:6:6:
2 kstep, kinc, jelem, params, nload, jdltyp, adlmag, predef, npredf,
1
Error: Unclassifiable statement at (1)
my_subroutine.for:7:6:
3 lfoags, mlvarx, ddlmag, mdload, pnewdt, jprops, njprop, period)
1
Error: Unclassifiable statement at (1)
aba_param.inc:17:57:
PARAMETER(IALLD=0,IRMMD=4,NEMPTY=0,ISPIND=2,IGRAD=0)
1
Error: Unexpected characters in PARAMETER statement at (1)
my_subroutine.for:12:6:
1 energy(7), coord(mcrd, nnode), u(ndofel), du(mlvarx, *), v(ndofel),
1
Error: Unclassifiable statement at (1)
my_subroutine.for:13:6:
2 a(ndofel), time(2), params(*), jdltyp(mdload, *), adlmag(mdload, *),
1
Error: Unclassifiable statement at (1)
my_subroutine.for:14:6:
4 ddlag(mdload, *), predef(2, npredf, nnode), lflags(4), jprops(*)
1
Error: Unclassifiable statement at (1)
my_subroutine.for:46:6:
svars(2) = fHolder
1
Error: Unclassifiable statement at (1)
my_subroutine.for:47:6:
rhs(3,1) = -fHolder
1
Error: Unclassifiable statement at (1)
my_subroutine.for:48:5:
else if(kstep.eq.3) then
1
Error: Non-numeric character in statement label at (1)
my_subroutine.for:48:5:
else if(kstep.eq.3) then
1
Error: Unclassifiable statement at (1)
my_subroutine.for:79:6:
rhs(3,1) = -fHolderNew
1
Error: Unclassifiable statement at (1)
my_subroutine.for:83:11: Error: 'svars' at (1) is not a variable
my_subroutine.for:84:11: Error: 'svars' at (1) is not a variable
my_subroutine.for:85:11: Error: 'svars' at (1) is not a variable
f951.exe: Error: Unexpected end of file in 'my_subroutine.for'
这种方法并不复杂,您不必担心密钥是否未提供或为空
query = {
join: [:comments],
where: {:author => 'Bob'}
}
如果键为空或根本不存在
Article.joins(query[:join]).where(query[:where])
#=> "SELECT `articles`.* FROM `articles` INNER JOIN `comments` ON `comments`.`article_id` = `articles`.`id` WHERE `articles`.`author` = 'Bob'"
或嵌套
query = {
join: []
}
Article.joins(query[:join]).where(query[:where])
#=> "SELECT `articles`.* FROM `articles`"
答案 1 :(得分:1)
我创建了以下查询,该查询将适用于任何模型和关联的链接查询数组。
def chain_queries_on(klass, arr)
arr.inject(klass) do |relation, query|
begin
relation.send(query[0], *query[1..-1])
rescue
break;
end
end
end
我在本地进行了以下测试,
arr = [['where', {id: [1,2]}], ['where', {first_name: 'Shobiz'}]]
chain_queries_on(Article, arr)
触发的查询如下所示,以返回正确的输出,
Article Load (0.9ms) SELECT `article`.* FROM `article` WHERE `article`.`id` IN (1, 2) AND `article`.`first_name` = 'Shobiz' ORDER BY created_at desc
注意-1:少数明显的情况
对于空的arr
,它将返回我们在方法中作为第一个参数传递的class
。
如果出现错误,它将返回nil
。如果我们使用pluck
会返回数组(输出不是可链接的),或者不将类作为第一个参数传递,则可能会发生错误。
可以对上面的内容进行更多的修改以改进并避免出现极端情况。
注2:改进
您也可以使用一个参数(即数组)将此方法定义为Object
类的类方法,并直接在类似这样的类上调用
# renamed to make concise
Article.chain_queries(arr)
User.chain_queries(arr)
内部方法,使用self
代替klass
答案 2 :(得分:0)
template<>
double get_data_at_timepoint<Foo>(const Foo &obj, size_t index) {
// Foo related implementation
}