给定具有三维坐标x,y和z的系统模型,我编写了以下实例方法,以便在所讨论的特定系统的设定范围内给出所有其他系统。这是代码:
def systems_within(range = '15')
System.find_by_sql(["SELECT * FROM systems WHERE Sqrt(Pow((:x - systems.x), 2) + Pow((:y - systems.y), 2) + Pow((:z - systems.z), 2)) <= :range AND id!= :current_id", {x: x, y: y, z: z, range: range, current_id: id}])
end
是否有ActiveRecord这样做?
答案 0 :(得分:2)
由于您需要访问当前实例,因此您需要保留实例方法,但是您可以通过将部件移动到范围中来将其分解(我猜这是ActiveRecord的意思)。
这样的事可能有用。这是未经测试的代码。
scope :within_range, -> (x, y, z, range = '15') {
where("Sqrt(Pow((:x - systems.x), 2) + Pow((:y - systems.y), 2) + Pow((:z - systems.z), 2)) <= :range", {x: x, y: y, z: z, range: range})
}
scope :excluding, -> (excluded_id) { where("id <> ?", excluded_id) }
def systems_within(range = 15)
System.excluding(id).within_range(x, y, z, range)
end
答案 1 :(得分:1)
您可以通过与数据库进行比较来让数据库执行更少的计算 范围广场:
new
&#34;选择*来自系统&#34;是隐式的,所以你只需要调用where子句。我将这些条件与SQL片段进行复杂的计算:
square_range = range**2
请注意,这里只使用System.where(
'Pow((:x - x), 2) + Pow((:y - y), 2) + Pow((:z - z), 2)) <= :square_range',
{x: x, y: y, z: z, square_range: square_range}
).where.not(id: current_id)
而不是x
,因为另一个systems.x
只是参数,而不是自己的数据库对象。
把这些全部放在范围内,就像Brad Pauly建议的那样,也是一个好主意。
顺便说一下,打电话给你的班级&#34;系统&#34;可能很危险,因为ruby有一个:x
方法来进行操作系统调用。