如何调用父类,而是创建其中一个孩子?

时间:2016-02-24 01:34:44

标签: ruby-on-rails ruby oop object model

我有一个这样的模型目录结构:

/alerts
   base_alert.rb
   panic_alert.rb
   hardware_alert.rb

alert.rb

使用/alerts/x_alert.rb模型设置如下:

class base_alert < ActiveRecord::Base
    ...
end

class panic_alert < base_alert
    ...
end

class hardware_alert < base_alert
    ...
end

etc.

有没有办法在top目录中调用alert.rb上的create,并且根据传递的参数,它会创建一个子节点而不是alert.rb。

即。 Alert.create({类型:&#34; panic_alert&#34;})

它会创建并返回一种panic_alert类型的警报吗?

3 个答案:

答案 0 :(得分:1)

您可以使用constantizesafe_constantize方法执行此操作。他们做的是取一个字符串并尝试返回字符串引用的类。例如:

"BaseAlert".safe_constantize
=> BaseAlert

def method_name(alert_type)
  alert_type.safe_constantize.create()
end

如果字符串不匹配,则constantize之间的差异会引发错误,而safe_constantize只会返回nil。请记住,如果您传入一个下划线字符串(例如panic_alert),那么您必须camelize

答案 1 :(得分:1)

通过对类定义进行少量更改,例如从Alert而不是ActiveRecord::Base继承BaseAlert,您可以实现您想要实现的目标。

以下是更新的课程:

# app/models/alert.rb
class Alert < ActiveRecord::Base

end

# app/models/alerts/base_alert.rb
module Alerts
  class BaseAlert < ::Alert

  end
end

# app/models/alerts/panic_alert.rb
module Alerts
  class PanicAlert < BaseAlert

  end  
end

# app/models/alerts/hardware_alert.rb
module Alerts
  class HardwareAlert < BaseAlert

  end
end 

以下是从基类创建子类的几种方法:

@panic_alert = Alert.create!(
  type: 'Alerts::PanicAlert', #this has to be string
  #other attributes
) 

@alert = Alert.new
@alert.type = 'Alerts::PanicAlert' #this has to be string
# assign other attributes, if necessary
@alert.save 

@alert = Alert.new
@panic_alert = @alert.becomes(Alerts::PanicAlert) #this has to be class
# assign other attributes, if necessary
@panic_alert.save

答案 2 :(得分:0)

在一生之前,我为此创建了StiFactory。也就是说,这些天我对STI没有多大用处(因此缺乏维护)。