【问题标题】:Multiple associations to same table with alias具有别名的同一个表的多个关联
【发布时间】:2014-06-09 19:55:47
【问题描述】:

我有一个不是用 Ruby 编写的遗留应用程序。旧版应用程序使用 SQL Server 数据库,而我的 Rails 应用程序需要访问此旧版数据库。

该数据库有一个 User 表、ViewKey 表和两个桥接表,它们实现了 User 和 ViewKey 之间的两个多对多关系。桥接表是 UserViewKeyAllowed 和 UserViewKeyDenied。因此,每个用户可能有多个他们被允许访问的查看密钥和多个他们被拒绝访问的查看密钥。

这是我定义的模型:

class User < ActiveRecord::Base
  self.table_name = 'tblUser'
  attribute_names.each { |attr| alias_attribute attr.underscore, attr }

  has_many :user_groups, foreign_key: :tblUserID
  has_many :user_view_key_alloweds, foreign_key: :tblUserID
  has_many :user_view_key_denieds, foreign_key: :tblUserID
  has_many :groups, through: :user_groups

  has_many :view_key_alloweds, through: :user_view_key_alloweds, source: :view_key
  has_many :view_key_denieds, through: :user_view_key_denieds, source: :view_key    
end

class ViewKey < ActiveRecord::Base
  self.table_name = 'tblViewKey'
  attribute_names.each { |attr| alias_attribute attr.underscore, attr }

  has_many :group_view_keys, foreign_key: :tblViewKeyID
  has_many :groups, through: :group_view_keys

  has_many :user_view_key_alloweds, foreign_key: 'tblViewKeyID'
  has_many :user_view_key_denieds, foreign_key: 'tblUserID'
end

class UserViewKeyDenied < ActiveRecord::Base
  self.table_name = 'tblUserViewKeyDenied'
  attribute_names.each { |attr| alias_attribute attr.underscore, attr }

  belongs_to :view_key, primary_key: 'ID', foreign_key: 'tblViewKeyID'
  belongs_to :user, primary_key: 'ID', foreign_key: 'tblViewKeyID'
end

class UserViewKeyAllowed < ActiveRecord::Base
  self.table_name = 'tblUserViewKeyAllowed'
  attribute_names.each { |attr| alias_attribute attr.underscore, attr }

  belongs_to :view_key, primary_key: 'ID', foreign_key: 'tblViewKeyID'
  belongs_to :user, primary_key: 'ID', foreign_key: 'tblUserID'
end

我的“has_many: ... through:”关联工作正常,以下 Ruby 似乎可以正确查询数据:

user = User.where(ID: 116).eager_load(:view_key_alloweds, :view_key_denieds).first

我希望能够执行以下操作:

user = User.where(ID: 116).eager_load(:view_key_alloweds, :view_key_denieds).where('tblViewKey.IsWebView = 1').first

我需要将第二个“where”扩展为“tblViewKey.IsWebView = 1 AND SomeAlias.IsWebView = 1”。有没有办法为 ViewKey 模型指定别名,或者有更好的方法吗?活动记录是否有命名表别名的标准方式?

我正在考虑使用范围,但我不确定如何为“has_many ... through”关联定义一个范围。

【问题讨论】:

    标签: ruby-on-rails activerecord model-associations


    【解决方案1】:

    经过更多研究,我能够提出一个可行且性能良好的解决方案。 Active Record 确实有一个用于在多次加入同一个表时创建表别名的方案。它似乎是关联名称加上加入的表的名称。因此,使用显示的模型,我可以查询我想要使用的数据:

    @user = User.where(ID: params[:user_id])
    .eager_load(:view_key_alloweds, :view_key_denieds, groups: [:view_keys])
    .where('[tblViewKey].IsWebView = 1 OR [view_key_denieds_tblUser].IsWebView = 1 OR [view_keys_tblGroup].IsWebView = 1')
    .first
    

    :view_key_alloweds 关联在对 eager_load 的调用中首先列出,因此我的 where 不需要别名来连接 tblViewKey 表。 :view_key_denieds 也加入到 tblViewKey 表,但由于它从 tblUser 表加入,我知道别名将是 [view_key_denieds_tblUser]。通过“groups: [:view_key]”的关联是通过 tblGroups 表完成的,因此别名将是 [view_keys_tblGroup]。

    我的代码有效,但我不知道如何利用正在生成的别名。 Rails 和 Active Record 的未来版本可能会破坏我的代码。 https://github.com/rails/rails/issues/12224 这里有一个关于别名的讨论,但我对 ruby​​、rails 和活动记录还很陌生,大部分都在我的脑海里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多