rails nomethoderror(对于#< activerecord::relation[]>,未定义的方法“< < ”):

dluptydi  于 2021-09-29  发布在  Java
关注(0)|答案(2)|浏览(393)

背景故事
我目前正在将RubyonRails应用程序更改为多数据库配置。切换的主要原因是将我的成员(用户)和配置文件表放在一个单独的数据库中,可以从另一个ror应用程序访问该数据库;因此,除了使用oauth和doorkeeper之外,我还可以使用单一登录功能。这是一个长时间的项目,有很多疯狂的障碍。最后,今晚似乎一切正常,直到我运行了规范测试,我今天做的一项工作就是扔旗。
以下是针对该问题的适当代码,为简洁起见进行了简化。
任何帮助都将不胜感激。非常感谢。
模型
app/models/members\u record.rb

class MembersRecord < ApplicationRecord
    self.abstract_class = true

    connects_to database: { writing: :members, reading: :members }
end

app/models/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

app/models/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

app/models/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 这段关系和全班同学不太Harmony Member 一旦该类引用了另一个数据库上的数据。正在生成的sql查询失败。因此,我创建了一个方法,并调用了 whereMember 模型这给了我一份我正在寻找的成员名单。我不得不在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多个不同的示例 << 用于将成员或任何对象添加到被引用的列表中。
如果你需要任何进一步的细节,请告诉我。再次感谢你!

wlsrxk51

wlsrxk511#

这在rails 7上本机支持(看见https://edgeguides.rubyonrails.org/active_record_multiple_databases.html#handling-与跨数据库连接的关联,https://github.blog/2021-07-12-adding-support-cross-cluster-associations-rails-7/ 及https://github.com/rails/rails/pull/41937)
如果您真的需要,我可能会建议您转到rails master,并使用本机方式:

has_many :members, 
         through: :approved_group_members, 
         class_name: "Member", 
         source: :member, 
         disable_joins: true
nkcskrwz

nkcskrwz2#

我想去重写你可以去的rails大师。
您可以尝试将对象从activerecord关系转换为activerecord集合代理对象,然后我们使用这种方法。我认为这不是一种好的方法

相关问题