Project Import: calculate `UNIQUE_RELATIONS` instead of keeping an explicit list in the code
UNIQUE_RELATIONS
is an edge case in our Import/RelationFactory, which could be integrated into GroupProjectObjectBuilder
or a separate object.
Being an edge case, it's extremely error-prone, as it is completely undiscoverable for the person who adds a relation from the product side.
This implicitness leads to new relations having a unique index on project_id
or project_id
as a primary key not being imported which is a bug.
The idea is to drop an explicit UNIQUE_RELATIONS
list from the codebase in favor of calculating it in place.
Please check the discussion for the additional info:
The following discussion from !20174 (merged) should be addressed:
-
@georgekoltsov started a discussion: (+9 comments) Looks like both
ci_cd_settings
andproject_feature
relations are not being imported, but rather skipped, since by the time we try to import, these settings already exists (because ofafter_save/create
callbacks on project creation).There might be a need for a new object builder specific for these types of cases.
Just a quick note on purpose of
GroupProjectObjectBuilder
. This might be known information, but wanted to reiterate anyway. Main purpose of this class is to instead of always building a new object, we attempt to find and reuse already created ones, to avoid situations of duplicate records of relations likeMilestone
,Label
. For example, if 2 issues have 1 label applied, this class will reuse and return this label, instead of creating a duplicate. Similar to milestones, we want to link to existing milestones instead of creating new ones.In this case it looks like what we want to do is to either completely recreate a record (i.e. destroy & create) or update attributes of an existing record. Current functionality does not provide this afaik (might be wrong). So there might be a need in new logic, given that a relation exists in
UNIQUE_RELATIONS
- we destroy that record & create new one, or update attributes of existing one - I am not sure if there are any validations that would prevent us from deleting that record.I know that ultimately we want to get rid of
UNIQUE_RELATIONS
. In this case we could reflect on association, and if it's ahas_one
relation, destroy & re-create / update it's attributes.e.g.
if @relation_class.reflect_on_association(:project) && Project.reflect_on_association(relation_sym).macro == :has_one @relation_class.find_by_project_id(@project.id).destroy object = @relation_class.new(inheritance_attributes) object.assign_attributes(parsed_relation_hash) object end
I did not test this but perhaps something like this is worth considering. Hope this helps