2

我正在为我的应用程序使用单表继承。我的多态类型是维护,现在只有一个子类型,名为 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]

如果我为 :type 键的值传入“OilChange”,则维护记录的类型是维护而不是 OilChange。我可以通过在 REPL 控制台中查找记录来验证这一点。类型字段为零。通过添加以下行,我可以让它像我想要的那样工作。

@log.maintenance.type = params[:maintenance][:type]

但这很丑陋。我想知道的是为什么 create 方法没有像 name 字段那样设置 type 字段?

您在我的 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

蒂亚!

4

2 回答 2

3

具体的答案是该type属性,就像 Rails 的许多特殊属性一样,受到保护,不会被批量赋值。:attr_protected(在文档中查找。)

更普遍的问题的答案是你不够信任你的模型。如果要创建 OilChange 类型的记录,则不应调用Maintenance.newMaintenance.create。调用OilChange.neworOilChange.create代替,Rails 会自动设置类型并为您完成所有后台工作。

于 2009-10-21T13:30:43.267 回答
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

当参数包含错误类型时,此代码将创建无效的维护类。如果它们包含正确的类型,则将创建指定类的实例。

如果您的模型使用命名空间,您可能会查看本文而不是使用 Module.const_get

于 2011-04-10T11:33:05.687 回答