Rails:复杂的设计选择:多态性?性传播感染?

发布于 2024-12-12 05:30:12 字数 1159 浏览 0 评论 0原文

我在设计这个应用程序时一直在尝试不同的技术,这对我来说非常复杂,因为有很多解决方案可供选择。决定这些解决方案中哪一个是最好的已经成为我过去几周的全职工作。

背景:

我有一个 User 模型,其中包含一些非常基本的身份验证功能。该应用程序将拥有三种不同类型的用户;管理员、买家和卖家。用户类型将在注册期间确定,其中复选框将询问用户是否是卖家。如果选中该框,则用户是卖家,如果未选中该框,则假设他们只是买家。我宁愿没有下拉菜单来选择用户类型(买家、卖家)。到目前为止很容易。

详细信息:

卖家有一个个人资料,访问该网站的用户将能够浏览不同的卖家并查看他们的个人资料。买家没有个人资料,不应在网站上列出以供用户查看。如果这还不够复杂,买家应该可以选择更改帐户类型并成为卖家。同样,卖家可以更改其帐户类型并“停用”其卖家帐户,将其从卖家列表中删除。

设计选项:

单表继承

当我尝试使用 STI 实现这一点时,我想到的结果并不是最优的。我面临两个选择:一个混乱的控制器,它根据上面提到的复选框决定创建什么类型的用户(一个控制器 - UsersController),或者两个相同的不同注册表单(两个控制器 - BuyersController) ,卖家控制器)。

has_one 或“has_none”配置文件关联

class User < ActiveRecord::Base
  has_one :profile # only if the user_type or role is "seller"
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

这里我将使用 CanCan 或 declarative_authorization 之类的东西,并让用户通过上面提到的复选框选择他/她的角色。这会带来安全风险,因为将会有一个管理员角色,而我不希望将其开放用于大规模分配。

我想无论你怎么看,我都会有一个混乱的控制器,其中包含如何创建用户的条件。除非我选择有两个复选框(“我是卖家”和“我是买家”),但这似乎是多余的。似乎无论我选择哪种设计,我都会面临一些黑客解决方案。

也许引入一些介于 User 和用户类型之间的模型?

有什么意见吗?

I have been trying different techniques while designing this application, which to me is very complicated as there are many solutions to chose from. Deciding which of these solutions is the best has become my full time job for the last few weeks.

Background:

I have a User model which contains some very basic authentication functionality. The application will have three different types of users; admins, buyers, and sellers. The user type will be determined during sign up, where a check box will ask if the user is a seller. If the box is checked, the user is a seller, and if the box is unchecked, it's assumed their just a buyer. I would rather not have a drop down menu to select the user type (Buyer, Seller). Easy so far.

Details:

Sellers have a profile, and users who visit the site will be able to browse through the different sellers and view their profile. Buyers do not have a profile, and should not be listed on the site for users to see. If that's not complicated enough, buyers should have the option to change their account type and become a seller. Similarly, sellers can change their account type and "deactivate" their seller account, removing them from the list of sellers.

Design options:

Single table inheritance:

What I came up with when attempting to implement this using STI was suboptimal. I was faced with two options: a messy controller, which made the decision of what type of user to create based on the check box mentioned above (one controller - UsersController), or two different sign up forms that were identical (two controllers - BuyersController, SellersController).

has_one or "has_none" Profile association:

class User < ActiveRecord::Base
  has_one :profile # only if the user_type or role is "seller"
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

Here I would use something like CanCan or declarative_authorization, and let the user chose his/her role via the check box mentioned above. This introduces a security risk, as there will be an admin role and I don't want this to be open for mass assignment.

I guess either way you look at it I'll have a messy controller with conditionals on how to create the user. Unless I choose to have two check boxes ("I am a seller," and "I am a buyer"), but this seems redundant. It also seems as though whichever design I choose, I'll be faced with some hackish solutions.

Maybe introduce some model that lies between the User and user type?

Any opinions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小忆控 2024-12-19 05:30:12

我真的不认为你需要 STI 或多态性。单个用户模型就足够了。我会向您的用户模型添加三种方法(管理员?、买家?、卖家?),并添加仅返回买家、卖家或管理员的范围。

就您而言,听起来您的用户角色数量确实最少(现在是 2 个,管理员扩展到 3 个)。我可能会使用 Ryan 在 “嵌入式关联” Railscast 中讨论的技术。

我在最新的项目中做了一些非常类似的事情,然后在此基础上使用了 CanCan(在我的例子中,是 2.0 alpha 分支,因为我发现它更简单)。你的能力类看起来像这样(在 2.0 语法中,但你可以用 1.x 做同样的事情,我确信)

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.seller?
      can :create, :profile
    else
      ...
    end
  end
end

I don't really think you need either STI or Polymorphism. A single user model should suffice. I would add three methods to your user model (administrator?, buyer?, seller?) and also add scopes that will return only buyers, only sellers, or only admins.

In your case, it sounds like you have a real minimal number of roles for users (2 now, expanding to 3 with admins). I would probably use the technique Ryan discusses in the "Embedded Associations" Railscast.

I've done something very similar in my latest project, and then used CanCan (in my case, the 2.0 alpha branch, as I find it simpler) on top of that. Your ability class would look something like this (in 2.0 syntax, but you can do the same with 1.x, I'm sure)

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.seller?
      can :create, :profile
    else
      ...
    end
  end
end
云醉月微眠 2024-12-19 05:30:12

到目前为止,听起来您有一个指示其用户类型的标志,或者一个字符串类型的列等。

您还没有指示任何依赖于此的行为 - 没有显示在列表中等可以用范围来处理。管理员可以用标志来处理。

我还没有看到这个问题,至少不是几周范围内的问题。

So far it sounds like you have a flag that indicates their user type, or a column with type string, etc.

You haven't indicated any behavior that depends on this--not showing up in listings etc. can be handled with scopes. Admin can be handled with a flag.

I don't see the problem yet, at least not a problem of a few weeks scope.

-残月青衣踏尘吟 2024-12-19 05:30:12

第三个选择。

...买家应该可以选择更改其帐户类型并成为
一个卖家。同样,卖家可以更改其帐户类型并
“停用”他们的卖家帐户,将其从列表中删除
卖家。

您是否考虑过不允许切换帐户?如果买家想成为卖家,那么他们会创建一个新的“卖家”帐户。对于卖家和买家来说,这都是一样的。这意味着有 2 个控制器用于注册等,但它会保持您正在寻找的分离。如果两者必须互斥,您可以进行基本的电子邮件检查以验证用户是否尚未拥有帐户,如果有,则必须在创建新帐户之前停用现有帐户。

A 3rd option.

...buyers should have the option to change their account type and become
a seller. Similarly, sellers can change their account type and
"deactivate" their seller account, removing them from the list of
sellers.

Have you considered not allowing switching of accounts? If a buyer wants to become a seller, then they create a new "seller" account. It would work the same for seller to buyer. It would mean having 2 controllers for the signup, etc. but it would keep the separation you're looking for. If the two must be mutually exclusive you could do a rudimentary email check to verify the user doesn't already have an account and if they do, they must de-activate the existing account prior to creating a new one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文