带有CRUD和Rails中的表单的单表继承

时间:2021-08-15 23:28:19

I'm a bit confused about STI in rails.

我对STI在rails上有点困惑。

My situation: I have a Contact model that has description and data string fields, to store some contact like phone, fax, email, etc.

我的情况:我有一个有描述和数据字符串字段的联系模型,用来存储一些联系,如电话、传真、电子邮件等。

Now when I have some specific contact type like phone number of email address I want to walidate the data format in different way and I want to make some different formating on output.

现在,当我有一些特定的联系人类型时,比如电子邮件地址的电话号码,我想以不同的方式来确定数据格式,我想在输出上做一些不同的格式化。

I decided to use STI as all the models have the same data with just different behaviour. And I have some questions regarding forms and CRUD operations as I don't want to go against Rails conventions.

我决定使用STI,因为所有模型都有相同的数据,只是行为不同。我有一些关于表单和CRUD操作的问题,因为我不想违背Rails约定。

  1. How do I make a dropdown list in form with model type? Should I hardcode it or is there some more automated way?

    如何用模型类型制作下拉列表?我应该硬编码,还是有更自动化的方法?

  2. How do I create a record? Should I use switch statement and according to received type create new model of according instance?

    如何创建记录?我是否应该使用switch语句并根据接收类型创建新的模型?

  3. How should I update it if I'm going to change the model type? Cast the object to new class? Or create a new object and destroy the previous one?

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

I'll be very thankfull for your help!

我将非常感谢你的帮助!

2 个解决方案

#1


2  

  1. Yes, should do a hardcore as there no default store for your STI models.
  2. 是的,应该做一个核心,因为你的STI模型没有默认的存储。
  3. Generally, yes. But With Rails you could just use camelize.constantize to get class from string. Another way is just use parent model, and set type field manually. As with STI all records are in the same table and then all are of the parent class.
  4. 一般来说,是的。但是对于Rails,你可以使用camelize。常量化以从字符串获取类。另一种方法是使用父模型,并手动设置类型字段。与STI一样,所有记录都在同一个表中,然后都属于父类。
  5. If you wish to update, just update type field. Then you could re-query to force Rails to get new object of different type.
  6. 如果您希望更新,只需更新类型字段。然后可以重新查询以强制Rails获取不同类型的新对象。

#2


0  

You could create a model like this :

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

Type < ActiveRecord::Base
  has_many :contacts
end

You could use this command rails g model Type name:string, add a type_id column in your contact and migrate the database.

您可以使用这个命令rails g模型类型名称:string,在您的联系人中添加一个type_id列,并迁移数据库。

end change your contact's model like this :

结束改变你的联系人的模式如下:

Contact < ActiveRecord::Base
  belongs_to :type
end

Now, in your form, you could use this :

现在,在你的表格中,你可以用这个:

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

It should resolve your problem.

它应该能解决你的问题。

Now you can do something like this :

现在你可以这样做:

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

Or use scopes.

或使用范围。

#1


2  

  1. Yes, should do a hardcore as there no default store for your STI models.
  2. 是的,应该做一个核心,因为你的STI模型没有默认的存储。
  3. Generally, yes. But With Rails you could just use camelize.constantize to get class from string. Another way is just use parent model, and set type field manually. As with STI all records are in the same table and then all are of the parent class.
  4. 一般来说,是的。但是对于Rails,你可以使用camelize。常量化以从字符串获取类。另一种方法是使用父模型,并手动设置类型字段。与STI一样,所有记录都在同一个表中,然后都属于父类。
  5. If you wish to update, just update type field. Then you could re-query to force Rails to get new object of different type.
  6. 如果您希望更新,只需更新类型字段。然后可以重新查询以强制Rails获取不同类型的新对象。

#2


0  

You could create a model like this :

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

Type < ActiveRecord::Base
  has_many :contacts
end

You could use this command rails g model Type name:string, add a type_id column in your contact and migrate the database.

您可以使用这个命令rails g模型类型名称:string,在您的联系人中添加一个type_id列,并迁移数据库。

end change your contact's model like this :

结束改变你的联系人的模式如下:

Contact < ActiveRecord::Base
  belongs_to :type
end

Now, in your form, you could use this :

现在,在你的表格中,你可以用这个:

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

It should resolve your problem.

它应该能解决你的问题。

Now you can do something like this :

现在你可以这样做:

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

Or use scopes.

或使用范围。