ruby-on-rails - 具有不同列 Rails 的相同模型

标签 ruby-on-rails ruby activerecord devise

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

它们有一些共同的列,也有一些不同的列。每个用户是否应该有一个单独的详细信息表(develop_detailsdriver_details)?此外,可以与他们建立关系。

否则,我可以对所有列使用相同的模型,并只获取所需的(其他当然是零)。

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

最佳答案

你可能想看看单表继承

尝试一个 DeveloperDriver 都继承自 User 并共享一个 users 数据库表。每个模型实际上都是自己的模型,允许您定义完全独立的关联、回调、验证、实例方法等...

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

您需要向 users 添加一个 type 列。所有 DeveloperDriver 列字段也应该为 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

您还可以为 type 列使用 enum,如果需要,可以覆盖默认的 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

关于ruby-on-rails - 具有不同列 Rails 的相同模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45339248/

相关文章:

ruby-on-rails - rails 5 : STI With Has Many Through Association

ruby-on-rails - 在 ActiveRecord 中

ruby-on-rails - 我是否需要去除标签以改进搜索?

ruby - 元编程:如何发现对象的真实类?

ruby - 如何使Searchkick/Elasticsearch where子句不区分大小写?

ruby-on-rails - 在 rails 中使用 ActiveRecord 从数据库返回每第 n 行

ruby-on-rails - 在 RoR 中,如何从 "Failed to open TCP connection ... (general SOCKS server failure)"错误中恢复?

mysql - rails db:migrate rails 中止! Mysql2::错误:用户 'root' @'localhost' 的访问被拒绝(使用密码:是)

ruby-on-rails - Errno::ECONNREFUSED:连接被拒绝 - connect(2) for action mailer

ruby-on-rails - Rails 获得验证失败错误,但 ActiveRecord 错误模型中没有错误