具有不同列的相同模型 [英] Same Model with different columns Rails
问题描述
我有2个用户角色 Developer
和 Driver
。它们都在 User
模型下,但是都有不同的详细信息,例如Developer的 hourly_rate
,技能
,经验
,全名
,并且驾驶员拥有 cars_he_can_drive
, hours_driven
,全名
等。
I have 2 user roles Developer
and Driver
. They both are under an User
model, but also both have different details such as Developer has hourly_rate
, skills
, experience
, full_name
and Driver has cars_he_can_drive
, hours_driven
, full_name
etc.
它们有一些公用的列,也有一些不同的列。每个用户是否应该有单独的明细表( develop_details
, driver_details
)?而且,可以与他们建立关系。
They have some common columns and some different ones as well. Should there be a separate detail table (develop_details
, driver_details
) for each of the User? and further, relationships can be made with them.
否则,我可以对所有列使用相同的模型,并且仅获取所需的列(其他列当然为零)。
Else I can have same model with all columns and fetch only the ones required (others will be nil ofcourse).
更新
我在用户表中使用角色as和integer,然后使用枚举。
我正在将Rails 5与devise 4.3.0一起使用。
UPDATE Im using role as and integer in user table and then using enums. I'm using Rails 5 with devise 4.3.0.
推荐答案
您可能想看看Single Table Inheritance
You probably want to look at Single Table Inheritance
尝试从两者继承的 Developer
和 Driver
User
并共享一个 users
数据库表。每个有效地都是其自己的模型,允许您定义完全独立的关联,回调,验证,实例方法等...
Try a Developer
and Driver
that both inherit from User
and share one users
database table. Each is effectively its own model, allowing you to define totally independent associations, callbacks, validations, instance methods, etc...
它们共享所有相同的数据库列,并且 User
类中定义的任何内容都将被继承(并且可以被覆盖)。
They share all of the same database columns, and anything defined in the User
class will be inherited (and can be overwritten).
您需要添加类型
列提供给用户
。所有 Developer
和 Driver
列字段都应为 users $ c定义
You will need to add a type
column to users
. All of the Developer
and Driver
columns fields should be defined for the users
table as well.
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
您可以像对其他模型一样对它们运行单独的查询
You can run separate queries for them just as you would any other model
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
编写关联的方式与使用
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
您还可以使用枚举
作为类型
列,并覆盖默认的 type
列名称(如果您希望
You can also use enum
for the type
column, and override the default type
column name if you wish
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
使用枚举是您必须使用大写的名称,并且所有
枚举
辅助方法和范围也将大写。
The catch with using enum
is you will have to use the capitalized name, and all of your enum
helper methods and scopes will be capitalized as well.
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
这篇关于具有不同列的相同模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!