背后的故事
我目前正在将我的 Ruby on Rails 应用程序更改为多数据库配置。切换的主要原因是将我的 Member(User) 和 Profile 表放在单独的数据库中,可以从另一个 RoR 应用程序访问;因此,除了使用 OAuth 和 Doorkeeper 之外,我还可以拥有单点登录功能。这是一个许多小时的项目,有许多疯狂的障碍。最后今晚似乎一切正常,直到我进行了规格测试,而我今天所做的工作之一就是扔旗子。
这是问题的适当代码,为简洁起见进行了简化。
任何帮助将不胜感激。谢谢你。
楷模
应用程序/模型/members_record.rb
class MembersRecord < ApplicationRecord
self.abstract_class = true
connects_to database: { writing: :members, reading: :members }
end
应用程序/模型/member.rb
class Member < MembersRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable,
:validatable, :confirmable
has_one :member_map, dependent: :destroy
has_one :profile, dependent: :destroy
has_one :site_profile, dependent: :destroy
has_many :approved_group_members, -> { approved }, class_name: "GroupMember"
has_many :groups, through: :approved_group_members, class_name: "Group", source: :group
应用程序/模型/group.rb
class Group < ApplicationRecord
belongs_to :owner, class_name: 'Member'
belongs_to :organization, optional: true
has_many :group_members, dependent: :destroy
# Many of the lines below no longer work with Multiple DBs, as we can not INNER JOIN across DBs.
# They have been commented out and methods built in their place.
has_many :approved_group_members, -> { approved }, class_name: "GroupMember"
# has_many :members, through: :approved_group_members, class_name: "Member", source: :member
def members
Member.where(id: self.approved_group_members.pluck(:member_id))
end
has_many :invited_group_members, -> { invited }, class_name: "GroupMember"
# has_many :invited_members, through: :invited_group_members, class_name: "Member", source: :member
def invited_members
Member.where(id: self.invited_group_members.pluck(:member_id))
end
应用程序/模型/group_member.rb
class GroupMember < ApplicationRecord
belongs_to :group
belongs_to :member
enum status: { approved: 0, invited: 1, pending_approval: 2, banned: 3}
end
解决方法
现在,查看上面的代码,您应该会在组模型中看到一些有问题的解决方法。原始代码被注释掉了,下面有解决方法。这只是该代码:
# Many of the lines below no longer work with Multiple DBs, as we can not INNER JOIN across DBs.
# They have been commented out and methods built in their place.
has_many :approved_group_members, -> { approved }, class_name: "GroupMember"
# has_many :members, through: :approved_group_members, class_name: "Member", source: :member
def members
Member.where(id: self.approved_group_members.pluck(:member_id))
end
has_many :invited_group_members, -> { invited }, class_name: "GroupMember"
# has_many :invited_members, through: :invited_group_members, class_name: "Member", source: :member
def invited_members
Member.where(id: self.invited_group_members.pluck(:member_id))
end
这些变通办法的原因是,一旦该类引用不同数据库上的数据,该has_many
关系就无法与该类一起使用。Member
正在构建的 SQL 查询失败。因此,我创建了一个方法并where
在Member
模型上调用了 a 。这给了我正在寻找的成员名单。我必须在 9 次不同的情况下这样做。
现在我遇到的问题
在超过 100 个不同位置的代码中,我将成员或其他对象添加到给定列表中,例如使用此类代码的“受邀成员”。(这段代码具体在我的一个规范中,现在失败了)
it 'will set the GroupMember to approved if the group is invite only and member was invited' do
group_invitation
group.invited_members << member
expect { service.call! }.to change{GroupMember.count}.by(0)
expect(service.success?).to be_truthy
expect(service.success_message).to eq("You have successfully joined this group.")
expect(service.error).to eq("")
end
第二行读取group.invited_members << member
,然后我收到一条错误消息:
NoMethodError (undefined method `<<' for #<ActiveRecord::Relation []>):
我的问题
我完全理解错误在说明什么,但不知道如何纠正它。是否有其他方法可以解决问题以允许<<
保留?我非常希望只需要更改 9 次不同的解决方法,而不是重写 100 多个不同的实例,这些实例<<
用于将成员或任何对象添加到被引用的列表中。
如果您需要更多详细信息,请告诉我。再次感谢你!