【问题标题】:Two very different user models in DeviseDevise 中两种截然不同的用户模型
【发布时间】:2014-01-14 10:19:26
【问题描述】:

我的应用程序中有两种不同类型的用户,它们使用 Devise 通过 Rails 4 进行身份验证,但它们的字段非常不同。一个是买方,另一个是卖方。买方必须有位置和付款信息,而卖方没有。最初我认为创建两个独立的 Devise 模型是个好主意,但必须有更好的方法。我考虑过将它们全部保存在同一张表中,并对买家的付款数据进行序列化。

什么是好的解决方案?

【问题讨论】:

  • 你不做不同型号的原因是什么?它们肯定是不同的对象。
  • 当你显然有两个 Devise 模型时会出现很多问题
  • 您将获得每个模型的助手,例如 current_seller 和 current_buyer。但是,由于无论如何您都需要将它们分开,我认为这对您来说很容易。我正在与用户和 admin_users 一起做。如果您讨厌两个模型的想法,请查看cancan。它使您能够赋予用户角色,但它不适合您的用例。

标签: ruby-on-rails ruby devise ruby-on-rails-4 models


【解决方案1】:

看看 STI - 简而言之,您创建一个名为 User 的基本模型,然后创建两个子类 User::BuyerUser::Seller(不需要命名空间,但建议这样做)。两个模型都存储在同一个表中,应用于User 模型的所有内容都会影响这两个类。更多关于 STI here

更新:

如果您不希望有许多空表格单元格,您可以使用 1-1 关联来保留所有特定于类的详细信息。您还可以添加一个包装器来完全封装它。它可能看起来像这样:

class User < ActiveRecord::Base
  belongs_to :details, polymorphic: true

  def method_missing(method, *args)
    return details.send(method, *args) if details.respond_to? method
    super
  end
end

class BuyerDetails < ActiveRecord::Base
  has_one :user, as: :details

  # buyer_attribute column
end

class SellerDetails < ActiveRecord::Base
  has_one :user, as: details

  #seller_attribute
end

然后您可以将其与 STI 混合:

class User::Buyer < User
  def initialize(*args)
    super
    details = BuyerDetails.new
  end
end

class User::Seller < User
  def initialize(*args)
    super
    details = SelerDetails.new
  end
end

然后您可以使用以下方法进行简单的工作:

user = User::Buyer.new
user.buyer_attribute       #=> nil
user.seller_attribute      #=> NoMethod error!

注意:您需要在 User 模型和 details_id 上具有 details_type 字符串列,才能使多态关联起作用。对于 STI,您将需要另一列 type

【讨论】:

  • 如果 STI 真正共享的唯一字段是姓名、电子邮件和密码,这会是一件好事吗?
  • BroiSaste,如果买家也可以是卖家,卖家也可以是买家会怎样?多态关联有它自己的问题。
  • @VijayMeena - 哦,哇,这个答案现在已经超过 7 年了:D 在这种情况下,STI 不起作用 - 而是创建单个用户模型和单独的买家/卖家模型(或买家资料/卖家资料)属于用户。
【解决方案2】:

老实说,我改用多态关系。我保留了我的用户模型几乎用于身份验证,然后制作了两个新模型(买家和卖家),它们的字段并不相同。这与上面显示的 BroiSate 方法非常接近。

例子

class User < ActiveRecord::Base  
  belongs_to :authenticatable, polymorphic: true
end


class Buyer < ActiveRecord::Base  
  has_one :user, as: :authenticatable
  # Add buyer specific fields to this table
end

class Seller < ActiveRecord::Base   
  has_one :user, as: :authenticatable
  # Add seller specific fields to this table
end

【讨论】:

  • 如果明天需求发生变化,用户既可以是买家又可以是卖家怎么办?在我看来,多态关联可能无法随着需求的变化而很好地扩展。
猜你喜欢
  • 2017-03-29
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-26
  • 2014-12-09
  • 1970-01-01
相关资源
最近更新 更多