Ruby on rails 处理数据库视图的ActiveRecord模型';s字段作为整数而不是布尔值
我有一个链接到ActiveRecord模型的数据库视图。当我调用modelRuby on rails 处理数据库视图的ActiveRecord模型';s字段作为整数而不是布尔值,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我有一个链接到ActiveRecord模型的数据库视图。当我调用modelappendenceactivity.all时,它返回 [ [0] #<AdherenceActivity:0x007fec986b5328> { :adherence_date => Wed, 01 Nov 2017, :patient_id => 10000, :morning => 0.0,
appendenceactivity.all
时,它返回
[
[0] #<AdherenceActivity:0x007fec986b5328> {
:adherence_date => Wed, 01 Nov 2017,
:patient_id => 10000,
:morning => 0.0,
:afternoon => 1.0,
:evening => 1.0,
:night => nil
}
]
Rails 5.1、Ruby 2.4.1由于没有人对此作出回应,我将给出我的答案。我想我的方法是向类型类本身添加定义,然后像这样使用getter/setter
class AdherenceActivity < ApplicationRecord
def morning
#do nothing if nil
return if @morning.nil?
#convert to boolean
@morning.to_bool
end
def morning=(val)
super(val.to_f)
end
#And repeat for other boolean values...
end
class FalseClass; def to_f; 0.0 end end
class TrueClass; def to_f; 1.0 end end
class Float; def to_bool; not self.zero? end end
#NOTE: I am unsure what data type the DB/Rails is setting the 1s and 0s to
#But it looks like a float
然后,在从float到boolean的转换过程中,添加一个类到float,该类将检查它是否为零。 (0.0?==真,因此需要与之相反的值,例如,不是0.0?)
额外学分:
我建议添加上述方法,因为当您开始处理更复杂的情况时,它会使事情保持干爽、简短和甜蜜。
假设有很多不同的布尔值要转换
类依附活动
希望这有帮助。由于没有人对此作出回应,我将给出我的答案。我想我的方法是向类型类本身添加定义,然后像这样使用getter/setter
class AdherenceActivity < ApplicationRecord
def morning
#do nothing if nil
return if @morning.nil?
#convert to boolean
@morning.to_bool
end
def morning=(val)
super(val.to_f)
end
#And repeat for other boolean values...
end
class FalseClass; def to_f; 0.0 end end
class TrueClass; def to_f; 1.0 end end
class Float; def to_bool; not self.zero? end end
#NOTE: I am unsure what data type the DB/Rails is setting the 1s and 0s to
#But it looks like a float
然后,在从float到boolean的转换过程中,添加一个类到float,该类将检查它是否为零。 (0.0?==真,因此需要与之相反的值,例如,不是0.0?)
额外学分:
我建议添加上述方法,因为当您开始处理更复杂的情况时,它会使事情保持干爽、简短和甜蜜。
假设有很多不同的布尔值要转换
类依附活动
希望这会有所帮助。这与@brad axe发布的内容基本相同,但处理的是
nil
案例。我希望在ActiveRecord/Query级别上解决这个问题,因为这不会更改查询的返回值,而是更改在调用对象的晨/午/晚/晚时返回的值
我之所以选择@brad axe,是因为这是正确的选择,但为了清晰起见,我想发布我的解决方案
def morning
return if super.nil?
super == 1
end
def afternoon
return if super.nil?
super == 1
end
def evening
return if super.nil?
super == 1
end
def night
return if super.nil?
super == 1
end
这与@brad axe发布的内容基本相同,但处理的是
nil
案例。我希望在ActiveRecord/Query级别上解决这个问题,因为这不会更改查询的返回值,而是更改在调用对象的晨/午/晚/晚时返回的值
我之所以选择@brad axe,是因为这是正确的选择,但为了清晰起见,我想发布我的解决方案
def morning
return if super.nil?
super == 1
end
def afternoon
return if super.nil?
super == 1
end
def evening
return if super.nil?
super == 1
end
def night
return if super.nil?
super == 1
end
你能换个视角吗
sum
通常生成一个numeric
类型,因此产生1.0
和0.0
值。Oracle适配器是否对布尔值使用某种小整数(就像MySQL一样),或者Oracle中是否存在本机布尔值类型?基本上,您必须用生成布尔值的内容(如果该类型可用)替换和
,或者添加类型转换。@muistooshort遗憾的是没有。Oracle不支持布尔数据类型。它仅将它们表示为1或0。当您在迁移中指定了数据类型时,ActiveRecord将其解释为true/false。由于这是一个视图,我无法告诉AR它是一个布尔值(或者更确切地说,这是我的问题,我如何让AR将此字段解释为布尔值)您如何与视图交互?您能简单地覆盖上午
,下午
。。。方法?你能改变视图吗sum
通常生成一个numeric
类型,因此产生1.0
和0.0
值。Oracle适配器是否对布尔值使用某种小整数(就像MySQL一样),或者Oracle中是否存在本机布尔值类型?基本上,您必须用生成布尔值的内容(如果该类型可用)替换和
,或者添加类型转换。@muistooshort遗憾的是没有。Oracle不支持布尔数据类型。它仅将它们表示为1或0。当您在迁移中指定了数据类型时,ActiveRecord将其解释为true/false。由于这是一个视图,我无法告诉AR它是一个布尔值(或者更确切地说,这是我的问题,我如何让AR将此字段解释为布尔值)您如何与视图交互?您能简单地覆盖上午
,下午
。。。方法?这就是我今天早些时候走的路线。既然我们都得出了这个结论,我就告诉你重点。额外积分法很聪明,但我明确定义了每天早上/下午/晚上/晚上的方法,以明确说明这一点。FWIW我不需要setter方法,因为这是一个DB视图,不能更改值。这还需要处理nil
值,并保留returnnil
class AdherenceActivity < ApplicationRecord
#Your list of boolean/float columns
%w[morning afternoon evening night].each do |s|
#Getter methods
define_method(s) do
#do nothing if nil value received
return if self.instance_variable_get("@#{s}").nil?
#Get the instance variable with name, eg. @night
self.instance_variable_get("@#{s}").to_bool
end
#Setter methods
define_method("#{s}=") do |val|
super(val.to_f)
end
end
end
class FalseClass; def to_f; 0.0 end end
class TrueClass; def to_f; 1.0 end end
class Float; def to_bool; not self.zero? end end
#Assuming float data type
def morning
return if super.nil?
super == 1
end
def afternoon
return if super.nil?
super == 1
end
def evening
return if super.nil?
super == 1
end
def night
return if super.nil?
super == 1
end