我正在为我的应用程序使用单表继承。我的多态类型是维护,只有一个子类型,现在名为OilChange。我在控制器中的create方法中创建记录时遇到了问题。这是代码。
@log = Log.new(params[:log])
@log.maintenance = Maintenance.new(params[:maintenance])
params [:maintenance]哈希有密钥{:name,:type}。我可以通过如下打印来验证它们的存在和值
print params[:maintenance][:name]
print params[:maintenance][:type]
如果我输入“OilChange”作为:type键的值,则维护记录的类型为Maintenance,而不是OilChange。我可以通过在REPL控制台中查找记录来验证。类型字段为零。我可以通过添加以下行来使其工作。
@log.maintenance.type = params[:maintenance][:type]
但那很难看。我想知道为什么create方法不设置类型字段,因为它只是找到名称字段?
您在我的schema.rb
中看到的两种类型create_table "logs", :force => true do |t|
t.date "date"
t.text "description"
t.string "title"
t.string "summary"
t.integer "car_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "maintenance_id"
t.integer "mileage"
end
create_table "maintenances", :force => true do |t|
t.string "name"
t.string "type"
t.datetime "created_at"
t.datetime "updated_at"
t.string "oil_brand"
t.string "oil_type"
t.string "oil_filter_type"
我的模特看起来像这样。
class Log < ActiveRecord::Base
belongs_to :car
has_and_belongs_to_many :tags
belongs_to :maintenance
end
class Maintenance < ActiveRecord::Base
has_one :log
end
class OilChange < Maintenance
end
TIA!
答案 0 :(得分:3)
具体答案是,type
属性与许多Rails的特殊属性一样,受到质量分配的保护。 (在文档中查找:attr_protected
。)
更普遍的问题的答案是你不够信任你的模特。如果要创建OilChange类型的记录,则不应致电Maintenance.new
或Maintenance.create
。请改为调用OilChange.new
或OilChange.create
,Rails会自动负责设置类型并为您完成所有后台工作。
答案 1 :(得分:0)
请尝试以下代码:
begin
klass = Module.const_get(params[:maintenance][:type])
@log.maintenance = klass.new(params[:maintenance])
if ! @log.maintenance.is_a?(Maintenance)
@log.maintenance = Maintenance.new(params[:maintenance])
end
rescue NameError
@log.maintenance = Maintenance.new(params[:maintenance])
end
如果您想在数据库中只有维护的子类,请在维护类中执行以下操作:
class Maintenance < ActiveRecord::Base
validates_presence_of :type
# other stuff goes here
end
当params包含错误的类型时,此代码将创建无效的Maintenance类。如果它们包含正确的类型,则将创建指定类的实例。
如果您的模型使用名称空间,您可以查看this article而不是使用Module.const_get
: