【问题标题】:Database Model and associations solution数据库模型和关联解决方案
【发布时间】:2011-10-01 23:26:59
【问题描述】:

我有那些模型

User, Developer, App, Permission
  1. 用户可以拥有默认权限
  2. 用户可以拥有不同应用程序的权限
  3. 一个用户可以安装多个应用程序
  4. 用户也可以是应用程序的开发人员
  5. 开发者仍然是用户,可以拥有所有用户的权限(安装应用程序、默认权限、每个应用程序的权限)

到目前为止,我有:

用户.rb

class User < ActiveRecord::Base
  has_many :apps
end

app.rb

class App < ActiveRecord::Base
  has_many :permissions, :through => :app_permissions
end

permission.rb

class Permission < ActiveRecord::Base
  belongs_to :app
end

app_permission.rb

class AppPermission < ActiveRecord::Base
end

问题

  1. 如何区分用户? (Regular, Developer) 使用 CanCan 或 Rails STI 或 Simple Roles Class 更好吗?请说明为什么使用这三种解决方案中的任何一种或其他方法更好。
  2. 最好创建一个 Default_Permission 模型来将应用程序权限与默认权限分开吗?

编辑:

如果我错过任何信息,请询问。我想看看一些不同的解决方案以及每个解决方案的工作原理。谢谢

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3


    【解决方案1】:

    我会推荐以下内容:

    Developer 是一个 User 对象。 在架构中使用 is_developer 布尔值区分开发人员和用户。这将使用户/开发人员的集成变得更加容易(没有 switch 语句)。您可以添加命名范围以专门查找开发人员:

    class User < ActiveRecord::Base
      named_scope :regular_users, :conditions => { :is_developer => false }
      named_scope :developers, :conditios => { :is_developer => true }
      #you can then call User.regular_users or User.developers
    end
    

    或者,您可以让用户/开发人员作为多态关联工作。例如

    class Role < ActiveRecord::Base
      belongs_to :entity, :polymorphic => true #with entity_id / entity_type in your schema
    end
    

    这种方法的缺点是它会使您的代码更加复杂,而语义增益很少或为零。


    我并不真正理解您所说的默认权限是什么意思,但这似乎是一个与数据库相反的逻辑问题。每个人都有默认权限吗?然后你可以在 *after_create* 上添加它,或者在编写逻辑时,假设它是真的(或由布尔标志控制)。以下代码将为每个用户创建一个权限,创建后默认为true(对于现有用户,您可以通过手动/ rake任务添加权限)。

    class User < ActiveRecord::Base
      after_create :add_default_permission
    
      def add_default_permission
        Permission.default_permissions.each do |permission|
          self.app_permissions.create(:permission_id => permission.id)
        end
      end
    end
    

    至于 default_permissions,我建议在权限表上使用 *is_default* 布尔值。这样,您可以拥有多个默认权限(或稍后删除默认权限)。作为默认权限权限,无需区分对象模型。即

    class Permission < ActiveRecord::Base
      named_scope :default_permissions, :conditions => { :is_default => true }
    end
    

    最后,确保完整拼写出所有的 ActiveRecord 关联,即

    class User < ActiveRecord::Base
      has_many :apps
      has_many :permissions, :through => :app_permissions, :as => :permissible #edited
    end
    
    class App < ActiveRecord::Base
      belongs_to :app_permission
      has_many :permissions, :through => :app_permissions, :as => :permissible #edited
    end
    
    class Permission < ActiveRecord::Base
      belongs_to :app_permissions
      belongs_to :permissible, :through => :app_permissions, :polymorphic => true #edited
    end
    
    class AppPermission < ActiveRecord::Base
      belongs_to :permissible, :polymorphic => true #edited
      belongs_to :app
    end
    

    当用户安装应用程序时:以下为多态性编辑

    Class User < ActiveRecord::Base
      def get_required_app(app)
        required_permissions = []
        app.permissions.each do |p|
          if self.permissions.find(:first, conditions => { :permission_id => p.id } ).nil?
            required_permissions.push p
          end
        end
        required_permissions
      end
    
      def install_app(app)
        req = required_permissions app
        return req if req.count > 0
        #add user app
      end
    end
    

    希望这可以帮助您解决问题,如果您需要任何其他信息,请告诉我。

    【讨论】:

    • 使用默认权限我的意思是用户将拥有一些安装应用程序时默认的权限。安装应用程序后,用户可以修改特定应用程序的权限。
    • 那么权限是针对应用程序/用户的吗?例如。 Bob 安装了具有“Run on swings”权限的“Playground”,后来 Jane 安装了具有“Build a new seesaw”权限的 Playground?
    • 没有。应用程序可以写入磁盘、从磁盘读取、从磁盘删除等。用户可以有一些预定义的条件,例如从磁盘读取 = true,从磁盘删除 = false 所以每次他安装一个新应用程序时,他必须只接受他不接受默认权限的权限..
    • 您应该使用多态关系来定义用户/应用权限(见上,下)。当用户想要安装应用程序时,您可以查看该应用程序的哪些权限少于用户拥有的权限,并要求用户授予这些权限才能安装该应用程序。上面的代码应该会指导你如何设置这个场景。
    【解决方案2】:

    我无法从您的问题中看出您的具体业务需求是什么,但大多数人使用基于角色的模式进行权限管理。有关讨论和建议,请参阅 this question

    【讨论】:

    • 有多少种不同的权限?有多少不同的用户?与典型用户权限设置的不同方式相比,用户是否频繁出入?围绕基于角色的安全性的假设是相对静态的权限模式数量相对有限 - 例如。工作/职位 - 并且许多用户具有相同的权限模式并且经常来来往往。如果每个用户最终都将拥有一组独特的权限,那么基于角色的安全性可能没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 2011-08-21
    • 2013-03-29
    相关资源
    最近更新 更多