我有一个不是用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”关联定义一个。
答案 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和活跃的记录,其中大部分是我的头脑。