我有2个用户角色Developer
和Driver
。它们都属于User
模型,但两者都有不同的详细信息,例如开发人员hourly_rate
,skills
,experience
,full_name
和驱动程序cars_he_can_drive
1}},hours_driven
,full_name
等。
他们有一些共同的列和一些不同的列。每个用户是否应该有单独的详细信息表(develop_details
,driver_details
)?而且,可以与他们建立关系。
否则我可以在所有列中使用相同的模型,只获取所需的列(其他列为零)。
更新 我在用户表中使用角色as和整数,然后使用枚举。 我正在使用Rails 5和4.3.0设计。
答案 0 :(得分:4)
您可能希望查看单表继承
尝试继承Developer
并共享一个Driver
数据库表的User
和users
。每个都是它自己的模型,允许你定义完全独立的关联,回调,验证,实例方法等......
它们共享所有相同的数据库列,User
类中定义的任何内容都将被继承(并且可以被覆盖)。
您需要向type
添加users
列。还应为Developer
表定义所有Driver
和users
列字段。
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
答案 1 :(得分:0)
这两种方法都可以解决您的问题。就个人而言,我只会有一个表格,因为Developer
也是User
的类型,而Driver
也是User
的类型。你可以这样做:
class User < ActiveRecord::Base
end
class Developer < User
end
class Driver < User
end
如果用户是Developer,那么您可以为开发人员获取额外的列。没有列的零值可以很好。
答案 2 :(得分:0)
您可以根据不同列的数量来决定。如果不同列的数量多于此处的情况,请创建一个包含所有公共列的用户表和另外两个表(开发人员和驱动程序),这些表将包含一个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