具有不同列Rails的相同模型

我有2个用户角色DeveloperDriver 。 它们都属于User模型,但两者都有不同的细节,例如Developer有hourly_rateskillsexperiencefull_name和Driver有cars_he_can_drivehours_drivenfull_name等。

它们有一些共同的列和一些不同的列。 是否应为每个用户提供单独的详细信息表( develop_detailsdriver_details )? 而且,可以与他们建立关系。

否则我可以在所有列中使用相同的模型并仅获取所需的列(其他将为零)。

更新我在用户表中使用角色as和整数,然后使用枚举。 我正在使用Rails 5和设计4.3.0。

您可能希望查看单表inheritance

尝试inheritance自User并共享一个users数据库表的DeveloperDriver 。 每个都是有效的模型,允许您定义完全独立的关联,回调,validation,实例方法等…

它们共享所有相同的数据库列,并且User类中定义的任何内容都将被inheritance(并且可以被覆盖)。

您需要向users添加type列。 还应为users表定义所有DeveloperDriver列字段。

 class AddTypeColumnToUsers < ActiveRecord::Migration def change add_column :users, :type, :string end end 

和你的模特

 class User < ApplicationRecord end class Driver < User end class Developer < User end Driver.new.type # => "Driver" Developer.new.type # => "Developer" User.new.type # => nil User.new(type: 'Driver').class # => Driver User.new(type: 'Developer').class # => Developer User.new.class # => User 

您可以像对待任何其他模型一样为它们运行单独的查询

 Developer.all # queries all users WHERE type="Developer" Driver.all # queries all users WHERE type="Driver" User.all # queries all users no matter what type 

像对待任何其他模型一样编写关联,ActiveRecord将处理其他所有事情。

 class Company < ApplicationRecord has_many :users has_many :developers has_many :drivers end class User < ApplicationRecord belongs_to :company end class Driver < User belongs_to :company end class Developer < User belongs_to :company end c = Company.first c.developers # => All developers that belong to the Company c.drivers # => All drivers that belong to the Company c.users # => All users (including developers and drivers) that belong to the Company 

您还可以将enum用于type列,并根据需要覆盖默认type列名

 class AddTypeColumnToUsers < ActiveRecord::Migration def change add_column :users, :role, :integer end end class User < ApplicationRecord self.inheritance_column = :role # This overrides the the "type" column name default enum role: { Driver: 0, Developer: 1 } end class Driver < User end class Developer < User end 

使用enum是你将不得不使用大写的名称,并且你的所有enum助手方法和范围也将被大写。

 User.Driver # => Scope that returns all drivers Driver.all # => same as User.Driver User.first.Driver? # => Is the user a Driver? 

http://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html

http://siawyoung.com/coding/ruby/rails/single-table-inheritance-in-rails-4.html

那么这两种方法都可以解决你的问题 就个人而言,我只有一个表,因为Developer也是User类型, Driver也是User类型。 你可以这样做:

 class User < ActiveRecord::Base end class Developer < User end class Driver < User end 

如果用户是Developer,那么您可以为开发人员获取额外的列。 没有列的nil值很好。

您可以根据不同列的数量来决定。 如果此处的情况似乎更多的是不同列的数量,请创建一个包含所有公共列的用户表和另外两个表(开发人员和驱动程序),这些表将包含一个user_id以与用户进行映射。

还要创建一个名为roles的表。 角色将包含id和role_name(驱动程序,开发人员等),并在users表中添加role_id列。 即使您拥有两个以上的角色,此结构也将为您提供灵活性。

class User < ActiveRecord::Base end

class Driver < ActiveRecord::Base belongs_to :user end

class Developer < ActiveRecord::Base belongs_to :user end

class Role < ActiveRecord::Base end