单表继承与CRUD和Rails中的表单

时间:2012-07-20 11:40:35

标签: ruby-on-rails ruby-on-rails-3 forms crud sti

我对轨道中的STI感到有点困惑。

我的情况: 我有一个Contact模型,其中包含descriptiondata字符串字段,用于存储电话,传真,电子邮件等联系人。

现在,当我有一些特定的联系方式,如电子邮件地址的电话号码时,我想以不同的方式对数据格式进行逻辑删除,并且我想在输出上进行一些不同的格式化。

我决定使用STI,因为所有模型都具有相同的数据,只有不同的行为。我对表单和CRUD操作有一些疑问,因为我不想反对Rails约定。

  1. 如何在模型类型的表单中创建下拉列表?我应该对其进行硬编码还是采用更自动化的方式?

  2. 如何创建记录?我应该使用switch语句并根据收到的类型创建新的实例模型吗?

  3. 如果我要更改模型类型,应该如何更新?将对象转换为新类?或者创建一个新对象并销毁之前的对象?

  4. 我非常感谢你的帮助!

2 个答案:

答案 0 :(得分:2)

  1. 是的,应该做一个硬核,因为你的STI模型没有默认商店。
  2. 一般来说,是的。但是使用Rails,您可以使用camelize.constantize从字符串中获取类。另一种方法是使用父模型,并手动设置type字段。与STI一样,所有记录都在同一个表中,然后所有记录都是父类。
  3. 如果您想更新,只需更新type字段即可。然后你可以重新查询以强制Rails获取不同类型的新对象。

答案 1 :(得分:0)

你可以创建一个这样的模型:

Type < ActiveRecord::Base
  has_many :contacts
end

您可以使用此命令rails g model Type name:string,在联系人中添加type_id列并迁移数据库。

最终更改您的联系人模型:

Contact < ActiveRecord::Base
  belongs_to :type
end

现在,在您的表单中,您可以使用:

select("type", "type_id", Type.all.collect {|t| [ t.name, t.id ] }, { :include_blank => true })

它可以解决您的问题。

现在你可以这样做:

@emails = Type.find_by_name('email').contacts

或使用范围。