Rails:复杂的设计选择:多态?性病? [英] Rails: complicated design choice: polymorphism? STI?

查看:37
本文介绍了Rails:复杂的设计选择:多态?性病?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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.

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

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.

单表继承:

当我尝试使用 STI 实现这一点时,我想到的并不是最理想的.我面临两个选择:一个凌乱的控制器,它根据上面提到的复选框决定创建哪种类型的用户(一个控制器 - UsersController),或者两个相同的不同注册表单(两个控制器 - BuyersController,SellersController).

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 或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 之类的东西,让用户通过上面提到的复选框选择他/她的角色.这会带来安全风险,因为将有一个管理员角色,我不希望将其开放给大量分配.

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.

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

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

有什么意见吗?

推荐答案

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

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.

就您而言,听起来您的用户角色数量确实最少(现在 2 个,管理员扩展到 3 个).我可能会使用 Ryan 在 "Embedded Associations" Railscast 中讨论的技术.

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.

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

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

这篇关于Rails:复杂的设计选择:多态?性病?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆