class 用户的 superclass 不匹配 - 从 ActiveRecord::Base 继承
superclass mismatch for class User - inheriting from ActiveRecord::Base
我正在尝试找出我的超级class 不匹配错误。我读过的所有关于此的帖子都将问题描述为 User 在我的应用程序中被定义为 class 两次。
在我的例子中,它没有被定义两次。我有一个服务文件夹,其中有一个用户文件夹(用于用户服务 classes)。在该用户文件夹中,我有一个名为 organisation_mapper_service.rb 的文件,其中包含:
class User < ActiveRecord::Base
class OrganisationMapperService
def self.call(user: u)
new(user: user).call
end
def initialize(user: u)
self.user = user
end
def call
if matching_organisation.present?
# user.organisation_request.new(organisation_id: matching_organisation.id)
# user.update_attributes!(organisation_id: matching_organisation.id)
else
#SystemMailer.unmatched_organisation(user: user).deliver_now
end
end
private
attr_accessor :user
def matching_organisation
User::OrganisationMapperService.new(user).matching_organisation
end
end
end
除此之外,我的用户模型将用户定义为:
class User < ApplicationRecord
我认为按照我的方式定义服务 class 应该没问题,因为它继承自 ActiveRecord::Base 而不是 ApplicationRecord。
谁能看出我在这里做错了什么?我还能在哪里寻找用户的第二个定义?
采纳塞尔吉奥的建议
我更改用户组织映射器服务打开如下:
class User::OrganisationMapperService < ActiveRecord::Base
但是我的 Users::OrgRequestsController 出现错误,新定义如下:
def new
@all_organisations = Organisation.select(:title, :id).map { |org| [org.title, org.id] }
@org_request = OrgRequest.new#form(OrganisationRequest::Create)
matched_organisation = User::OrganisationMapperService.new(current_user).matching_organisation
@org_request.organisation_id = matched_organisation.try(:id)
end
然后错误消息说:
PG::UndefinedTable at /users/4/org_requests/new
ERROR: relation "user_organisation_mapper_services" does not exist
LINE 8: WHERE a.attrelid = '"user_organisation_mapper...
**采纳塞尔吉奥的建议(完全正确)**
我将服务 class 更改为:
class User::OrganisationMapperService
但随后我收到一条错误消息:
wrong number of arguments (given 1, expected 0)
该错误突出显示了我服务的这一行 class:
def initialize(user: u)
self.user = user
end
我不知道该怎么办,因为如果有来自用户的继承,我显然有一个用户。
您 是 定义 User
class 和两个单独的父 class。不要那样做。
应该是
class User::OrganisationMapperService
这样,您现有的 User
class 将被加载和使用,而不是创建一个新的。
I thought it should be fine to define the service class in the way I have because it inherits from ActiveRecord::Base rather than ApplicationRecord.
您示例中的服务 class 没有继承自任何内容。
即使您解决了所有其他问题,您实际上仍然在进行无限递归。
User::OrganisationMapperService.call(user: User.first)
相当于调用:
User::OrganisationMapperService.new(user: User.first).call
内部调用 matching_organisation
,因此相当于:
User::OrganisationMapperService.new(user: User.first).matching_organisation
与此同时,matching_organisation
调用
User::OrganisationMapperService.new(user).matching_organisation
就是要兜兜转转。
它没有的唯一原因是 wrong number of arguments (given 1, expected 0)
错误。这是因为在您的 matching_organisation
方法中它应该是 User::OrganisationMapperService.new(user: user)
而不是 User::OrganisationMapperService.new(user)
。
更新回复评论:
据我了解,User::OrganisationMapperService
是一项服务 class,它负责查找一些 Organisation
然后执行某种工作。
User::OrganisationMapperService#matching_organisation
方法实际上应该包含 returns 给定用户的匹配组织的代码。实施将完全取决于您构建数据库的方式,但我会举几个例子让您走上正轨或给您一些想法。
首先,您的 organisations
table 可能有一个 user_id
列。在这种情况下,您可以对 Organisation
模型进行简单查询并使用用户的 ID 执行搜索:
class User::OrganisationMapperService
def matching_organisation
# find the organisation and cache the result
@matching_organisation ||= ::Organisation.where(user_id: user).first
end
end
或者,您可能有某种加入 table,其中组织中可能有多个用户(仅针对此示例,我们称其为 table 'employments'):
class Employment < ApplicationRecord
belongs_to :user
belongs_to :organisation
end
我们可以在Organisation
模型中加入scopes (this is a must read)来辅助查询:
class Organisation < ApplicationRecord
has_many :employments
has_many :users, through: :employments
scope :for_user, ->(user) {
# return organisations belonging to this user
joins(:users).merge( Employment.where(user_id: user) )
}
end
最后,OrganisationMapperService#matching_organisation
方法变为:
class User::OrganisationMapperService
def matching_organisation
# find the organisation and cache the result
@matching_organisation ||= ::Organisation.for_user(user).first
end
end
我正在尝试找出我的超级class 不匹配错误。我读过的所有关于此的帖子都将问题描述为 User 在我的应用程序中被定义为 class 两次。
在我的例子中,它没有被定义两次。我有一个服务文件夹,其中有一个用户文件夹(用于用户服务 classes)。在该用户文件夹中,我有一个名为 organisation_mapper_service.rb 的文件,其中包含:
class User < ActiveRecord::Base
class OrganisationMapperService
def self.call(user: u)
new(user: user).call
end
def initialize(user: u)
self.user = user
end
def call
if matching_organisation.present?
# user.organisation_request.new(organisation_id: matching_organisation.id)
# user.update_attributes!(organisation_id: matching_organisation.id)
else
#SystemMailer.unmatched_organisation(user: user).deliver_now
end
end
private
attr_accessor :user
def matching_organisation
User::OrganisationMapperService.new(user).matching_organisation
end
end
end
除此之外,我的用户模型将用户定义为:
class User < ApplicationRecord
我认为按照我的方式定义服务 class 应该没问题,因为它继承自 ActiveRecord::Base 而不是 ApplicationRecord。
谁能看出我在这里做错了什么?我还能在哪里寻找用户的第二个定义?
采纳塞尔吉奥的建议
我更改用户组织映射器服务打开如下:
class User::OrganisationMapperService < ActiveRecord::Base
但是我的 Users::OrgRequestsController 出现错误,新定义如下:
def new
@all_organisations = Organisation.select(:title, :id).map { |org| [org.title, org.id] }
@org_request = OrgRequest.new#form(OrganisationRequest::Create)
matched_organisation = User::OrganisationMapperService.new(current_user).matching_organisation
@org_request.organisation_id = matched_organisation.try(:id)
end
然后错误消息说:
PG::UndefinedTable at /users/4/org_requests/new
ERROR: relation "user_organisation_mapper_services" does not exist
LINE 8: WHERE a.attrelid = '"user_organisation_mapper...
**采纳塞尔吉奥的建议(完全正确)**
我将服务 class 更改为:
class User::OrganisationMapperService
但随后我收到一条错误消息:
wrong number of arguments (given 1, expected 0)
该错误突出显示了我服务的这一行 class:
def initialize(user: u)
self.user = user
end
我不知道该怎么办,因为如果有来自用户的继承,我显然有一个用户。
您 是 定义 User
class 和两个单独的父 class。不要那样做。
应该是
class User::OrganisationMapperService
这样,您现有的 User
class 将被加载和使用,而不是创建一个新的。
I thought it should be fine to define the service class in the way I have because it inherits from ActiveRecord::Base rather than ApplicationRecord.
您示例中的服务 class 没有继承自任何内容。
即使您解决了所有其他问题,您实际上仍然在进行无限递归。
User::OrganisationMapperService.call(user: User.first)
相当于调用:
User::OrganisationMapperService.new(user: User.first).call
内部调用 matching_organisation
,因此相当于:
User::OrganisationMapperService.new(user: User.first).matching_organisation
与此同时,matching_organisation
调用
User::OrganisationMapperService.new(user).matching_organisation
就是要兜兜转转。
它没有的唯一原因是 wrong number of arguments (given 1, expected 0)
错误。这是因为在您的 matching_organisation
方法中它应该是 User::OrganisationMapperService.new(user: user)
而不是 User::OrganisationMapperService.new(user)
。
更新回复评论:
据我了解,User::OrganisationMapperService
是一项服务 class,它负责查找一些 Organisation
然后执行某种工作。
User::OrganisationMapperService#matching_organisation
方法实际上应该包含 returns 给定用户的匹配组织的代码。实施将完全取决于您构建数据库的方式,但我会举几个例子让您走上正轨或给您一些想法。
首先,您的 organisations
table 可能有一个 user_id
列。在这种情况下,您可以对 Organisation
模型进行简单查询并使用用户的 ID 执行搜索:
class User::OrganisationMapperService
def matching_organisation
# find the organisation and cache the result
@matching_organisation ||= ::Organisation.where(user_id: user).first
end
end
或者,您可能有某种加入 table,其中组织中可能有多个用户(仅针对此示例,我们称其为 table 'employments'):
class Employment < ApplicationRecord
belongs_to :user
belongs_to :organisation
end
我们可以在Organisation
模型中加入scopes (this is a must read)来辅助查询:
class Organisation < ApplicationRecord
has_many :employments
has_many :users, through: :employments
scope :for_user, ->(user) {
# return organisations belonging to this user
joins(:users).merge( Employment.where(user_id: user) )
}
end
最后,OrganisationMapperService#matching_organisation
方法变为:
class User::OrganisationMapperService
def matching_organisation
# find the organisation and cache the result
@matching_organisation ||= ::Organisation.for_user(user).first
end
end