与别名的同一个表的多个关联

时间:2014-06-09 19:55:47

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

我有一个不是用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”关联定义一个。

1 个答案:

答案 0 :(得分: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

在调用eager_load时首先列出了:view_key_alloweds关联,因此我的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和活跃的记录,其中大部分是我的头脑。