0

我正在尝试找出解决问题的最佳方法。我有一个 pages 表和一个 user_types 表。我正在尝试在页面上指定多种用户类型。他们将充当权限组。但是,我需要这样做两次。一次用于读取权限,一次用于编辑权限。这是一个例子:

主页有 3 种可以阅读的用户类型 - 管理员、超级管理员、公共 它有 2 种可以编辑的用户类型 - 管理员、超级管理员

我有一个 user_types 表:admin super admin public etc

我创建了两个映射表(一个用于读取,一个用于编辑): pages_user_read_types pages_user_edit_types

他们都有 page_id 和 user_type_id

有没有更好的方法来实现这一点?如果这是最好的方法,我需要帮助找出模型的关系。我有一个关系

  has_and_belongs_to_many :user_types, :join_table => :pages_user_read_types

如何为单独的字段指定两个关系?

谢谢

4

2 回答 2

1

至少,您可能想要添加一个Permission模型。如果它变得比您描述的更复杂,我也建议使用CanCan

class Permission < ActiveRecord::Base
  #table is id, page_id, user_type_id, and permission_type (string).
  belongs_to :page
  belongs_to :user_type
end

在您的控制器中,您可以构建一个过滤器链,如下所示:

class PagesController < ApplicationController
  before_filter :load_page
  before_filter :authorize_view!, only: [ :show ]
  before_filter :authorize_edit!, only: [ :edit ]

  def show
  end

  def edit
  end

  private
    def load_page
      @page = Page.find(params[:id])
    end

    def authorize_view!
      if !@page.permissions.where(user_type_id: current_user.user_type_id, permission_type: "view").exists?
        flash[:notice] = "You do not have permission to view that page."
        redirect to root_path
      end
    end

    def authorize_edit!
      if !@page.permissions.where(user_type_id: current_user.user_type_id, permission_type: "edit").exists?
        flash[:notice] = "You do not have permission to edit that page."
        redirect to root_path
      end
    end

end

(这假设您current_user的应用程序中有一个方法)。

于 2012-10-22T03:35:41.237 回答
1

在过去的几年里,Rails 中的 HABTM 关系似乎不再受到 Rails 开发人员的青睐has_many :through。唯一应该使用 HABTM 的时候是当您不需要有关两个模型之间关系的任何其他信息时。在您的情况下,您试图通过创建两个 HABTM 关系来模拟这一点,而您可以通过拥有一个具有可编辑属性的连接模型来有效地实现这一点。

在代码中,它看起来像这样:

class Page < ActiveRecord::Base
  has_many :page_permissions
  has_many :user_types, :through => page_permissions

  def editable_user_types
    page_permissions.includes(:user_types).where(:editable => true).map(&:user_type)
  end

  def read_only_user_types
    page_permissions.includes(:user_types).where(:editable => false).map(&:user_type)
  end      
end

class PagePermission < ActiveRecord::Base
  belongs_to :page
  belongs_to :user_type
  # When you create this model, you should have a boolean attribute for editable
end

class UserType < ActiveRecord::Base
  has_many :page_permissions
  has_many :pages, :through => :page_permissions
end

我认为遵循这种方法将允许您合并到一个连接表,如果您需要为PageUserType之间的关系( PagePermission)添加其他属性,将来会更好。

于 2012-10-22T03:38:23.513 回答