diff --git a/lib/versioning/ruby/index.spec.ts b/lib/versioning/ruby/index.spec.ts
index 3a155f4274167ee0d72106ade4119e7b60b0c652..f3a29ebeeaf92bf5e1501823413c6c90223716cf 100644
--- a/lib/versioning/ruby/index.spec.ts
+++ b/lib/versioning/ruby/index.spec.ts
@@ -513,6 +513,7 @@ describe('semverRuby', () => {
           '2.20.1',
         ],
         ['~> 6.0.0', '~> 5.2.0', 'replace', '5.2.4.1', '6.0.2.1'],
+        ['~> 5.0, < 6', '~> 4.0, < 5', 'replace', '4.7.5', '5.0.0'],
       ].forEach(
         ([expected, currentValue, rangeStrategy, fromVersion, toVersion]) => {
           expect(
diff --git a/lib/versioning/ruby/strategies/replace.ts b/lib/versioning/ruby/strategies/replace.ts
index 25eae772a4176fbd50eacc00e5add1c96b2c38c4..8c62949d2e064fa4b9b15713d8bb14b5ecae0127 100644
--- a/lib/versioning/ruby/strategies/replace.ts
+++ b/lib/versioning/ruby/strategies/replace.ts
@@ -45,6 +45,14 @@ function reduceOnePrecision(version: string): string {
   return versionParts.join('.');
 }
 
+export function matchPrecision(existing: string, next: string): string {
+  let res = next;
+  while (res.split('.').length > existing.split('.').length) {
+    res = reduceOnePrecision(res);
+  }
+  return res;
+}
+
 export default ({ to, range }: { range: string; to: string }): string => {
   if (satisfies(to, range)) {
     return range;
@@ -72,6 +80,15 @@ export default ({ to, range }: { range: string; to: string }): string => {
     }
     const newLastPart = bump({ to: massagedTo, range: lastPart });
     newRange = range.replace(lastPart, newLastPart);
+    const firstPart = range
+      .split(',')
+      .map((part) => part.trim())
+      .shift();
+    if (firstPart && !satisfies(to, firstPart)) {
+      let newFirstPart = bump({ to: massagedTo, range: firstPart });
+      newFirstPart = matchPrecision(firstPart, newFirstPart);
+      newRange = newRange.replace(firstPart, newFirstPart);
+    }
   }
   // istanbul ignore if
   if (!satisfies(to, newRange)) {