在Rails中处理不同的用户类型

时间:2011-10-17 22:13:23

标签: ruby-on-rails

我正在设计一个具有两个[包括管理员]用户类型的应用程序:买家和卖家。当用户注册时,假设他们注册只是购买某个东西[买方帐户]。但是,如果他们希望成为卖家,他们应该有一个选择让他们发布他们的待售物品,[成为卖家]。这一点很重要,因为用户可以在帐户类型之间来回切换。

当然,卖家也可以购买物品。

问题

我面临的问题是,卖家有profile个页面,买家可以在这些页面上查看待售商品,而买家则不会。但是,这两种用户类型都有一个My Account页面,可用于更新其信息。

可能的设计选择

单表继承

class User < ActiveRecord::Base
  has_one :profile
end

class Seller < User
  has_many :sale_items
end

class Buyer < User
  # nothing here.. I guess this is the "default" user type
end

我考虑过这种方法,因为那时我可以清楚地区分用户类型。例如,每个用户的显示页面都清楚地分开。但是,这可能导致每个控制器中重复的代码,并在用户类型之间切换时引入问题。


只需使用declarative_authorization或CanCan将功能添加到基本用户类型

class User < ActiveRecord::Base
  has_one :profile
  has_many :sale_items  # only for Sellers
                        # if the user is a seller, allow them to add sale_items
end

我想到了这种方法,因为卖方基本上是具有附加功能的买方,例如发布待售物品。但这可能导致很多视图逻辑。例如if @user.role == "seller" render _some_seller_partial。我也不喜欢在视图中检查硬编码字符串的想法。好吧,我想我可以做if @user.seller?

其他设计选择?

我真的很想知道其他人如何为这个应用程序建模。我已经考虑了几天了。

3 个答案:

答案 0 :(得分:3)

我会使用第二个选项,但是使用declarative_authorization而不是cancan,我将使用role_model Gem将角色存储在用户模型中。

class User < ActiveRecord::Base
  has_one :profile
  has_many :sale_items  # only for Sellers
                        # if the user is a seller, allow them to add sale_items

  #  t.integer :roles_mask , :default => 0    # for role_model
end

declarative_authorization比CanCan更强大,一旦项目需要更多/更复杂的角色,我发现它可以更好地扩展..

如果使用role_model Gem存储角色,它会将它们存储为roles_mask属性中的位图。 这意味着用户可以拥有许多角色,例如可以同时是卖方和买方,如果您愿意,可以是管理员或主持人。

请参阅:

http://railscasts.com/episodes/188-declarative-authorization

http://railscasts.com/episodes/189-embedded-association

http://railscasts.com/episodes/192-authorization-with-cancan

http://railscasts.com/episodes/193-tableless-model

http://everydayrails.com/2011/10/06/rails-authorization.html

http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/

答案 1 :(得分:1)

我会选择cancan选项。是一个美妙的宝石,有良好的文档,易于使用,积极地保持,并且你有很多教程(因为它是由Ryan Bates创建的宝石,来自Railscasts,你可以肯定你有一集它)

答案 2 :(得分:1)

我会使用cancan选项,并使用draper gem作为视图逻辑。这两个宝石都有Railscast。

http://railscasts.com/episodes/286-draper