具有不同列的相同模型 [英] Same Model with different columns Rails

查看:84
本文介绍了具有不同列的相同模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆