rails如何应对不同类型的用户?

How to deal with different type of users with rails?

我想知道,是否有办法使用单一模型处理 Rails 中不同类型的 users/clients。

我真正需要做什么? - 我需要在我的数据库中保存不同类型的客户。所以,我有这个迁移:

class CreateClients < ActiveRecord::Migration
  def change
    create_table :clients do |t|
      t.string :name                       # Person name if "Personal", Company name if  type "Company"
      t.string :nif                        # fillable only if type is Company
      t.string :identity_card_number       # fillable only if type is Personal
      t.integer :client_type               # Type can be Personal or Company
      t.references :company, index: true   # if type is personal, it can belong to a company
      t.timestamps null: false
    end
  end
end

然后我创建这个模型

class Client < ActiveRecord::Base
    has_many :employees, class_name: 'Client', foreign_key: 'company_id'
    belongs_to :company, class_name: 'Client'
end

注意:个人账号可以属于公司,也可以不属于公司。

根据您的经验,我这样做是否正确?还有其他方法吗?

编辑:

嗨@manfergo25,

我还有一个问题。 "Company"和"Personal"都是"Clients Account",这样的话,两者都必须能够购买服务。

如果我需要将客户与服务相关联,我可以这样做吗?

class Personal < Account
   has_many :services
end

class Service < ...
   belongs_to :account
end

??

正如 Sontya 所说,正确的方法是单一 Table 继承 (STI)。

  class Account < ActiveRecord::Base
  end

然后,

  class Client < Account
  end

  class Provider < Account
  end

您只需在 'Account' 中添加一个类型列,以包含表示存储对象类型的字符串。

例如在控制器中你可以这样做:

account = Client.find(params[:autocomplete_client])     
params[:service][:account_id] = account.id
@service = Service.new(params[:service])

就我个人而言,我认为您在问题中建议的方式就是我要做的方式。

虽然单一 Table 继承在智力上是更好的建模——我发现 STI 有点难以处理,有时在 Rails 中不可靠。并且最终可能不会提高代码的整洁度或简洁度。如果您发现 OP 方法在允许您编写清晰简洁的代码方面效果不佳,并且 STI 似乎可以更好地工作,那么将 STI 作为一种选择牢记在心。

但我会在没有 STI 的情况下开始,只有一个客户 class,正如您在问题中所概述的那样。如果您稍后添加 STI,您仍然会有客户端 class,您只会有子 classes,例如,PersonalClient 和 CompanyClient。如果您愿意,以后切换到 STI 并不难,尽管它可能需要对数据库模式进行一些小的改动。

但我认为它不会给您带来足够的好处来证明增加的复杂性是合理的,在 Rails 的领域有时会有一些粗糙的边缘。

这里有一些关于 STI 的更多信息及其优缺点:http://eewang.github.io/blog/2013/03/12/how-and-when-to-use-single-table-inheritance-in-rails/

您可以使用 STI(单一 Table 继承)

class Account < ActiveRecord::Base
end

class Company < Account
    has_many :services, :dependent => :destroy
end

class Personal < Account
    has_many :services, :dependent => :destroy

end

class Service < ActiveRecord::Base
    belongs_to: personal
    belongs_to: company
end

根据上面的定义,personalcompany应该可以购买服务。 你应该可以打电话 @company.services # 它将return 你公司的服务数量 @personal.services#它将return你的个人服务数量