首页 > 解决方案 > 如何设置一个类的 2 个别名 has_and_belong_to_many 关系?

问题描述

我正在开发基于属性和基于角色的访问控制的授权管理。我需要将角色与(用户)组相关联,并将可用功能与(用户)组相关联。Role 类和 Feature 类都不存在,它们被定义为从 Parameter 类中提取的选项列表。总而言之,我尝试在 Parameter 类和 Group 类之间创建 2 个 HABTM 关系。

关系建立在角色编辑表单中。这是我的代码:

  <div class="row mat-form-row">
    <div class="mat-form-field col-md-6">
      <%= f.label :roles, t('Roles'), class: "mat-form-field-label" %>
      <%= f.collection_select :role_ids, list_of_user_roles, :id, :name, { }, { multiple: true, class: "mat-input-element select2-candidate" } %>
    </div>
    <div class="mat-form-field col-md-6">
      <%= f.label :feature, t('Features'), class: "mat-form-field-label" %>
      <%= f.collection_select :feature_ids, list_of_app_features, :id, :name, { }, { multiple: true, class: "mat-input-element select2-candidate" } %>
    </div>
  </div>
</div>

其中 list_of_users_roles 和 list_of_app_features 是从参数表中提取的。

使用默认结构创建了一个链接表来存储 nn 关联:

class CreateTableGroupsParameters < ActiveRecord::Migration[5.2]
  def change
    create_table "groups_parameters", id: :serial do |t|
      t.references :parameter, index: true
      t.references :group,  index: true
      t.boolean "is_active",                       default: true,  comment: "As nothing can be deleted, flags objects removed from the knowledge base"
      t.datetime "active_from",                    default: -> { 'current_date' }, comment: "Validity period"
      t.datetime "active_to"
      t.timestamps
    end
  end
end

模型已链接并设置了强大的参数:

##group.rb
  has_and_belongs_to_many :roles, :class_name => "Parameter"
  has_and_belongs_to_many :features, :class_name => "Parameter"

##parameter.rb
  has_and_belongs_to_many :groups

##groups_controller
    # Never trust parameters from the scary internet, only allow the white list through.
    def group_params
      params.require(:group).permit(:name, :description, :role, :territory_id, :organisation_id, :created_by, :updated_by, :code, :role_ids => [], :feature_ids => [])
    end

分别为每个关系(角色或特征)创建链接是成功的。但是当两者一起实现时,更新一个值列表只会起作用。最糟糕的是,更新另一个会删除之前的更新!

你有解决这个问题的建议吗?非常感谢!

标签: ruby-on-railsactiverecordhas-and-belongs-to-many

解决方案


感谢 Beartech 询问更多细节,我意识到这个问题可能比我这边的语法误解更复杂。实际上,控制台显示管理这些值列表意味着对每个列表删除连接表中不需要的记录的内容。考虑到has_and_belong_to_many方法的默认行为,我使用默认命名连接表,因此只创建了一个表。使用他的表有两个关系,第二个删除第一个设置的内容。

解决方案是创建 2 个单独的表来支持 2 个关系,并指定每个 has_and_belongs_to_many 方法调用使用哪个表:

class CreateTablesGroupsParameters < ActiveRecord::Migration[5.2]
  def change
    create_table "groups_roles", id: :serial do |t|
      t.references :parameter, index: true
      t.references :group,  index: true
      t.boolean "is_active",                       default: true,  comment: "As nothing can be deleted, flags objects removed from the knowledge base"
      t.datetime "active_from",                    default: -> { 'current_date' }, comment: "Validity period"
      t.datetime "active_to"
      t.timestamps
    end
    create_table "groups_features", id: :serial do |t|
      t.references :parameter, index: true
      t.references :group,  index: true
      t.boolean "is_active",                       default: true,  comment: "As nothing can be deleted, flags objects removed from the knowledge base"
      t.datetime "active_from",                    default: -> { 'current_date' }, comment: "Validity period"
      t.datetime "active_to"
      t.timestamps
    end
  end
end

在模型中:

 ##group.rb
  has_and_belongs_to_many :roles, :class_name => "Parameter", :join_table => "groups_roles"
  has_and_belongs_to_many :features, :class_name => "Parameter", :join_table => "groups_features"

感谢您支持我寻找解决方案。


推荐阅读