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
根据上面的定义,personal
和company
应该可以购买服务。
你应该可以打电话
@company.services
# 它将return 你公司的服务数量
@personal.services
#它将return你的个人服务数量
我想知道,是否有办法使用单一模型处理 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
根据上面的定义,personal
和company
应该可以购买服务。
你应该可以打电话
@company.services
# 它将return 你公司的服务数量
@personal.services
#它将return你的个人服务数量