【问题标题】:Boolean vs. Enum vs. Flag布尔值与枚举与标志
【发布时间】:2021-01-23 02:49:58
【问题描述】:

我正在开发一个允许用户登录的网站。所有用户都有一个账号,一个账号可以有多个订单。用户可以是客户、工作人员或经理。客户既不是工人也不是经理。经理也是工人。我想根据登录用户的类型展示页面/导航选项的其他部分。

目前我正在使用一组布尔值将用户标记为特定类型,测试该值,并运行一些 if/elsif 块以生成用户看到的页面。

class User
  include DataMapper::Resource
  # ...
  # various properties
  # ...
  property :client, Boolean
  property :worker, Boolean
  property :manager, Boolean
end

然后我使用 before 过滤器来测试用户类型并将结果设置为变量。

before do
  @user = session[:user]
  if @user.client?
    @ura = 'client'
  elsif @user.worker?
    @ura = 'worker'
  elseif @user.manager?
    @ura = 'manager'
  end
end

那么在我看来,我有@ura 可以玩。在我看来,这已经会给我的经理带来麻烦,因为@ura 必须既是工人又是经理。我可以在我的观点中使用一些或,但我认为更好的解决方案是将用户类型设置为枚举或标志。但我真的不明白如何在我的过程中使用它。

我想知道每种方法的优缺点是什么,以及如何在@ura 中获得适当值的基本示例。

【问题讨论】:

    标签: ruby sinatra datamapper ruby-datamapper


    【解决方案1】:

    我不确定,但可能是一个数组会是更好的解决方案:

    class User ....
       def getRoles
          roles = Array.new
          roles << "client" if self.client? 
          roles << "manager" if self.manager? 
          roles << "worker" if self.worker? 
          roles
       end
    end
    
    before do
      @user = session[:user]
      if(@user.getRoles.index("manager") != nil)
        ...
    

    【讨论】:

    • 这有点像我的想法。似乎使用像property :role, Enum[ :client, :worker, :manager ] 这样的东西基本上会给我你在一行中描述的内容。我的理解是,某事一次只能是 一个 枚举。 (即user.role = :worker 将覆盖 :role 的任何当前值)Flag 可以将任何定义的值作为属性保存。我得到Enum,但我不明白Flag 的关系(即如何设置和取消设置Flag 的特定值?*(一旦设置它们就可以取消设置?)*)
    • 理想情况下,我希望能够拥有.client? 之类的东西并返回truefalse。这样我就可以做类似if @ura.client? 的事情。 (我可以自己弄清楚代码,我只是想掌握表示该信息的最佳方式。)
    【解决方案2】:

    我不记得我是如何解决这个确切问题的(我认为是针对自行车送货应用程序),但今天才注意到它仍然没有答案。

    所以,就在十年后,即使我不再经常使用 DataMapper,但他是我现在解决这个问题的方法;

    当时我并不完全了解系统中用户Role 的身份验证和授权之间的区别。

    class User
      include DataMapper::Resource
      ...
      properties
      ...
      property :role, Enum[ :client, :worker, :manager ]
    end
    
    class Employee < User
      include DataMapper::Resource
      ...
       more properties
    end
    

    这样所有用户都可以拥有他们需要的东西,员工可以进一步分成WorkerManager。然后您可以对相应的模型进行适当的验证。前期代码更多,但更易于维护且更易于扩展,只需向 User 枚举和相应的类添加一个新角色。

    如果该类除了命名空间/逻辑分离之外没有做任何事情,您甚至可以通过一些元编程/反射从枚举中推断类并在初始化时包含适当的模块。

    【讨论】:

      猜你喜欢
      • 2011-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多