Ruby on rails Rails:ActiveRecord使用where和自定义比较器

Ruby on rails Rails:ActiveRecord使用where和自定义比较器,ruby-on-rails,ruby,activerecord,rails-activerecord,Ruby On Rails,Ruby,Activerecord,Rails Activerecord,我有一个名为Update的模型,它包含一个字符串列:version 类更新Gem::Version.new('2.0.1')) 我想做一个查询,在那里我可以得到version高于某个数字的所有记录。是否有方法将自定义方法传递到。其中,以便我可以使用版本比较器?例如: 类更新Gem::Version.new(该版本) 结束 结束 Update.where(&:version\u大于) 正如您所看到的,前面提到的代码不起作用,因为我需要将一个版本字符串传递到该方法中,而我似乎无法通过&:执行

我有一个名为
Update
的模型,它包含一个字符串列
:version

类更新
version
列包含字符串值,如
1.0.1
。使用
Gem::Version
,您可以像这样比较版本号:

Gem::Version.new('2.1')>Gem::Version.new('2.0.1'))
我想做一个查询,在那里我可以得到
version
高于某个数字的所有记录。是否有方法将自定义方法传递到
。其中
,以便我可以使用版本比较器?例如:

类更新Gem::Version.new(该版本)
结束
结束

Update.where(&:version\u大于)

正如您所看到的,前面提到的代码不起作用,因为我需要将一个版本字符串传递到该方法中,而我似乎无法通过
&:
执行该操作。是否有更好的方法来执行此操作,以便我只需比较
。where
调用中的值?我尽量避免拆分大/小/等数字,因为我只是在那里重新设计轮子。

不,你不能这样使用它

&
运算符将方法转换为过程,并在调用接受块的方法(如那些可枚举方法)时将参数传递给它。查看此线程以获取更多信息

where
方法不使用块。当您调用
where(…)
时,实际上是在调用
WhereChain.new(…)
。请参阅此处:


可以通过将该方法包装到sql对象中,或者简单地将其包装为返回sql字符串的方法来完成。但不幸的是,我认为sql(特别是mysql)没有类似于
的比较操作,您不能在数据库中使用Ruby方法,而
中的所有内容都是在数据库中执行的。但是,您可以在数据库中实现简单的
major.minor.patch
版本号比较

PostgreSQL支持数组列和数组逐元素比较,因此:

array[1,2,3] < array[1,5,0]
应该负责数据库。然后你可以说:

def version_is_greater_than(that_version)
  self.version > that_version.split('.').map(&:to_i)
end
或查询数据库:

def self.version_is_greater_than(that_version)
  where('version > array[?]', that_version.split('.').map(&:to_i))
end
您需要更新读取和写入
version
s的代码,以说明
version
列的新类型


或者,您可以将
version
保留为数据库中的字符串,并在
中使用
regexp\u split\u to\u array
,当您需要比较时,在其中调用:

where(%q{
  regexp_split_to_array(version, '\\.')::int[] > array[?]
}, that_version.split('.').map(&:to_i))


PL/Ruby允许您用Ruby编写存储过程,但它已经七年没有更新了,并且假设Ruby 1.8.7是最新版本。我们可以假装它不存在。

我在用Postgres。可接受简单的
1.2.3
格式。这与我的任何gem版本都没有关系,但我认为比较器至少满足了我的需要。我认为做这个
Update.all.select{u|gem::Version.new(u.Version)>gem::Version.new(“2.0”)}
但我只是想知道是否有一种方法可以将它与
。where
结合起来,以便根据其他属性过滤结果。
where(%q{
  regexp_split_to_array(version, '\\.')::int[] > array[?]
}, that_version.split('.').map(&:to_i))