Ruby on rails 处理数据库视图的ActiveRecord模型';s字段作为整数而不是布尔值

Ruby 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,

我有一个链接到ActiveRecord模型的数据库视图。当我调用model
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
值,并保留return
nil
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