问题描述
我正在尝试找出我的超类不匹配错误。我所读过的所有文章都将问题描述为用户在应用程序中两次被定义为类。
I am trying to figure out my superclass mismatch error. All the posts I've read about this describe the problem as being that User is defined twice as a class in my application.
对于我来说,它没有定义两次。我有一个服务文件夹,其中有一个用户文件夹(用于用户服务类)。在该用户文件夹中,我有一个名为Organisation_mapper_service.rb的文件,其中:
In my case, it isn't defined twice. I have a services folder and within that I have a user folder (for user service classes). In that user folder, I have a file called organisation_mapper_service.rb, with:
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
与此分开,我有我的用户模型,将用户定义为:
Separate to that, I have my user model which defines user as:
class User < ApplicationRecord
我认为以我的方式定义服务类应该没问题,因为它继承自ActiveRecord :: Base而不是ApplicationRecord。
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.
有人可以在这里看到我做错了吗?我还能在哪里找到用户的第二个定义?
Can anyone see what I've done wrong here? Where else could I look for a second definition of User?
接受塞尔吉奥的建议
我将用户组织映射器服务更改为打开,如下所示:
I change the user organisation mapper service to open as follows:
class User::OrganisationMapperService < ActiveRecord::Base
但是这给我的Users :: OrgRequestsController一个错误,其新定义为
But that then gives an error with my Users::OrgRequestsController which has new defined as follows:
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
the然后出现错误消息:
the error message then says:
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...
**接受SERGIO的建议(完全)**
**TAKING SERGIO'S SUGGESTION (exactly) **
我将服务等级更改为:
class User::OrganisationMapperService
但随后出现一个错误,提示:
But then I get an error that says:
wrong number of arguments (given 1, expected 0)
该错误突出显示了我的服务类别的这一行:
That error highlights this line of my service class:
def initialize(user: u)
self.user = user
end
我不知道该怎么做,因为如果从用户那里继承下来,我显然拥有一个用户。
I don't know what to do about that because I clearly have a user if there is an inheritance from user.
推荐答案
即使您解决了所有其他问题,实际上仍然可以进行无限次递归。
Even once you solve all your other issues, you actually have an infinite recursion going on.
User::OrganisationMapperService.call(user: User.first)
等同于调用:
User::OrganisationMapperService.new(user: User.first).call
内部调用 matching_organisation
,因此相当于:
Which internally calls matching_organisation
, so is sort of equivalent to:
User::OrganisationMapperService.new(user: User.first).matching_organisation
同时, matching_organisation
通话
User::OrganisationMapperService.new(user).matching_organisation
它会绕圈旋转。
唯一的原因不是因为个错误的参数数量(给定1,预期为0)
错误。这是因为它应该是 User :: OrganisationMapperService.new(user:user)
而不是 User :: OrganisationMapperService.new(user)
在您的 matching_organisation
方法中。
The only reason it doesn't is because of the wrong number of arguments (given 1, expected 0)
error. This is because it should be User::OrganisationMapperService.new(user: user)
rather than User::OrganisationMapperService.new(user)
in your matching_organisation
method.
根据评论进行更新:
据我了解, User :: OrganisationMapperService
是一个服务类,用于查找一些组织
,然后执行某种工作。
From what I understand, the User::OrganisationMapperService
is a service class that does the job of finding some Organisation
and then performing some sort of work.
User :: OrganisationMapperService#matching_organisation
方法实际上应包含返回给定用户的匹配组织的代码。实现将完全取决于您如何构造数据库,但是我将提供一些示例以使您走上正确的道路或提出想法。
The User::OrganisationMapperService#matching_organisation
method should actually contain the code that returns the matching organisation for the given user. The implementation will completely depend on how you have structured your database, but I'll give a couple of examples to put you on the right track or give you ideas.
首先,您的 organizations
表可能具有 user_id
列。在这种情况下,您可以对组织
模型进行简单的查询,然后使用用户的ID进行搜索:
First, Your organisations
table may have a user_id
column. In this case you could do a simple query on the Organisation
model and perform a search using the user's id:
class User::OrganisationMapperService
def matching_organisation
# find the organisation and cache the result
@matching_organisation ||= ::Organisation.where(user_id: user).first
end
end
或者,您可能有某种加入表,其中一个组织可能有多个用户(仅在此示例中,我们将此表称为雇员):
Alternatively, you may have some sort of join table where there may be multiple Users at an Organisation (just for this example let us call this table 'employments'):
class Employment < ApplicationRecord
belongs_to :user
belongs_to :organisation
end
可以将添加到组织
模型来协助查询:
We can add scopes (this is a must read) to the Organisation
model to assist with the query:
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
这篇关于类用户的超类不匹配-从ActiveRecord :: Base继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!