{"id":14866,"date":"2026-09-27T17:30:00","date_gmt":"2026-09-27T12:00:00","guid":{"rendered":"https:\/\/www.allerin.com\/blog\/?p=14866"},"modified":"2026-09-25T11:19:21","modified_gmt":"2026-09-25T05:49:21","slug":"rails-7-2-to-8-0-upgrade","status":"publish","type":"post","link":"https:\/\/www.allerin.com\/blog\/rails-7-2-to-8-0-upgrade\/","title":{"rendered":"Rails 7.2 to 8.0 without replacing your stack"},"content":{"rendered":"<p>A Rails 7.2 to 8.0 upgrade should preserve the parts of an application that already work while making the required code and dependency changes visible. Treating every Rails 8 announcement as another migration turns a framework upgrade into several projects sharing one failure log.<\/p>\n<p>Rails 7.2 left its published security-support window on 9 August 2026; Rails 8.0&#8217;s window ends 7 November 2026. Use 8.0 as a tested checkpoint on the way to 8.1. The <a href=\"https:\/\/rubyonrails.org\/maintenance\" target=\"_blank\" rel=\"noopener\">maintenance schedule<\/a> makes that destination a planning requirement, not a reason to combine every change in one deployment.<\/p>\n<p>For this article, an AI-assisted experiment generated a Rails 7.0.10 application and carried it through 7.1.6, 7.2.3.2 and 8.0.5.1. It uses Sprockets, Sidekiq, a Redis cache, Devise and Rack::Attack. This is a small historical fixture with deliberate upgrade cases, not an Allerin client application or a simulation of years of production traffic.<\/p>\n<p>Its source-version baseline passed 13 tests and 45 assertions. The final suite passed 15 tests and 47 assertions after adding malformed-request cases. A real Sidekiq worker also processed a queued shipment and persisted its new status.<\/p>\n<nav style=\"padding: 16px 20px; margin: 24px 0; background: #edf4f0; border-left: 3px solid #437e73; font-size: 16px; line-height: 1.6;\" aria-label=\"Article sections\">\n<p style=\"margin: 0 0 8px;\"><strong>Jump to a section<\/strong><\/p>\n<ul style=\"display: flex; flex-wrap: wrap; gap: 8px 24px; list-style: none; padding: 0; margin: 0;\">\n<li style=\"margin: 0;\"><a href=\"#separate-the-framework-change-from-the-defaults\">Upgrade decisions<\/a><\/li>\n<li style=\"margin: 0;\"><a href=\"#run-this-before-you-branch\">Before you branch<\/a><\/li>\n<li style=\"margin: 0;\"><a href=\"#check-devise-reset-token-continuity\">Devise reset tokens<\/a><\/li>\n<li style=\"margin: 0;\"><a href=\"#read-app-update-conflicts-as-changes-to-application-behavior\">Configuration conflicts<\/a><\/li>\n<li style=\"margin: 0;\"><a href=\"#fix-enum-definitions-while-the-earlier-release-can-warn\">Enums<\/a><\/li>\n<li style=\"margin: 0;\"><a href=\"#test-the-defaults-that-can-change-an-otherwise-green-suite\">Framework defaults<\/a><\/li>\n<li style=\"margin: 0;\"><a href=\"#params-expect-is-a-separate-request-handling-change\">Request parameters<\/a><\/li>\n<li style=\"margin: 0;\"><a href=\"#the-asset-and-job-backends-have-separate-histories\">Assets and jobs<\/a><\/li>\n<li style=\"margin: 0;\"><a href=\"#what-to-do-this-week\">This week\u2019s actions<\/a><\/li>\n<\/ul>\n<\/nav>\n<h2 id=\"separate-the-framework-change-from-the-defaults\" style=\"scroll-margin-top: 128px;\">Separate the framework change from the defaults<\/h2>\n<p>The Rails version in <code>Gemfile.lock<\/code> and the version passed to <code>config.load_defaults<\/code> control different things. Updating the bundle changes available APIs and gem requirements. Advancing <code>load_defaults<\/code> changes a collection of behaviors. Existing applications can take those decisions in separate commits, following the <a href=\"https:\/\/guides.rubyonrails.org\/upgrading_ruby_on_rails.html#configure-framework-defaults\" target=\"_blank\" rel=\"noopener\">framework-defaults upgrade process<\/a>.<\/p>\n<p>The first column records changes observed in this fixture. The other columns separate optional adoption from work that would obscure this hop&#8217;s results.<\/p>\n<div style=\"overflow-x: auto;\" tabindex=\"0\" role=\"region\" aria-label=\"Rails 7.2 to 8.0 upgrade decisions\">\n<table style=\"width: 100%; min-width: 700px; table-layout: fixed; border-collapse: collapse; font-size: 16px; line-height: 1.55;\" aria-label=\"Rails 7.2 to 8.0 upgrade decisions\">\n<thead>\n<tr>\n<th style=\"padding: 14px; border: 1px solid #d3dfdb; background: #edf4f0; text-align: left; vertical-align: top;\" scope=\"col\">changes for you<\/th>\n<th style=\"padding: 14px; border: 1px solid #d3dfdb; background: #edf4f0; text-align: left; vertical-align: top;\" scope=\"col\">does not change unless you opt in<\/th>\n<th style=\"padding: 14px; border: 1px solid #d3dfdb; background: #edf4f0; text-align: left; vertical-align: top;\" scope=\"col\">do not do during this hop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">The old enum declaration raises <code>ArgumentError<\/code> on 8.0. Pass the enum name positionally and preserve its numeric mapping.<\/td>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">Existing Sprockets can remain when its integration and processors are compatible. Propshaft is the new-app default.<\/td>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">Replace the asset pipeline merely to match a newly generated application.<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">The pinned <code>sqlite3<\/code> 1.7.3 gem prevents the 8.0 SQLite adapter from loading. This fixture needed a gem satisfying <code>&gt;= 2.1<\/code>.<\/td>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">Sidekiq and the explicit Redis cache configuration remain in place. Solid backends require a separate adoption.<\/td>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">Combine queue storage, cache storage and framework changes in one deployment.<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">Loading 8.0 defaults changes the fixture&#8217;s timeout, time-conversion and HTTP-freshness checks. The same Rails bundle passes with 7.2 defaults.<\/td>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\"><code>require<\/code> and <code>permit<\/code> remain available. <code>expect<\/code> changes request-shape handling when you adopt it.<\/td>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">Bulk-convert optional parameter roots without testing missing and malformed input.<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\"><code>app:update<\/code> proposes changes to locally configured files. Its proposed application configuration omitted the fixture\u2019s explicit queue, cache and time-zone settings.<\/td>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">Kamal, Thruster and the authentication generator are optional choices for an existing application.<\/td>\n<td style=\"padding: 14px; border: 1px solid #d3dfdb; text-align: left; vertical-align: top; overflow-wrap: anywhere;\">Replace deployment or Devise because Rails 8 offers alternatives.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2 id=\"run-this-before-you-branch\" style=\"scroll-margin-top: 128px;\">Run this before you branch<\/h2>\n<ul>\n<li>Record the exact Ruby, Rails and dependency versions, the database adapter and server, and the effective defaults, job adapter and cache store.<\/li>\n<li>Run the suite on the source version and preserve its warnings. Cover sign-in, failed sign-in, sign-out and password reset alongside your application&#8217;s authorization behavior.<\/li>\n<li>Exercise a real queue and cache in an isolated environment. A fake job adapter or memory cache cannot establish that the deployed backend still works.<\/li>\n<li>Precompile the actual asset manifests and load a page that references the compiled assets.<\/li>\n<li>Check dependency advisories and resolve necessary gem updates in separately tested commits where both Rails versions permit them.<\/li>\n<\/ul>\n<p>Ruby stayed at 3.3.12 throughout. Rails 8&#8217;s <a href=\"https:\/\/github.com\/rails\/rails\/blob\/v8.0.5.1\/rails.gemspec\" target=\"_blank\" rel=\"noopener\">gemspec<\/a> requires Ruby 3.2 or later, but <a href=\"https:\/\/www.ruby-lang.org\/en\/downloads\/branches\/\" target=\"_blank\" rel=\"noopener\">Ruby 3.2 reached end of life on 1 April 2026<\/a>. A minimum dependency version is not a current runtime recommendation. A move to Ruby 3.4 should have its own checks.<\/p>\n<h3 id=\"check-devise-reset-token-continuity\" style=\"scroll-margin-top: 128px;\">Check Devise reset-token continuity<\/h3>\n<p>Devise moved from 4.9.4 to 5.0.4 in a separately tested commit on Rails 7.2. Its <a href=\"https:\/\/github.com\/heartcombo\/devise\/blob\/v5.0.4\/CHANGELOG.md\" target=\"_blank\" rel=\"noopener\">changelog<\/a> records Rails 8 integration work and changes to secret selection; current advisories also rule out presenting the old fixture pin as deployment advice. Keeping Devise means preserving the authentication architecture while reviewing its dependency changes.<\/p>\n<p>The cross-version reset test found the reason for that review. Devise 4 used the fixture&#8217;s credentials-derived key; Devise 5 used the Rails application key. Supplying the same Rails environment secret did not make those effective Devise keys equal, and the old reset token was rejected.<\/p>\n<p>In a controlled after-upgrade copy, preserving the earlier effective Devise key allowed that same token to reset the password once; reuse was rejected. This is conditional on the application&#8217;s key sources, not a failure every Devise upgrade will encounter. Record the effective key&#8217;s continuity without printing it.<\/p>\n<h2 id=\"read-app-update-conflicts-as-changes-to-application-behavior\" style=\"scroll-margin-top: 128px;\">Read app:update conflicts as changes to application behavior<\/h2>\n<p>After the targeted bundle update, run the generator and inspect the resulting diff.<\/p>\n<pre style=\"overflow-x: auto; max-width: 100%;\"><code class=\"language-sh\">bin\/rails app:update\r\ngit diff -- config bin public\r\nbin\/rails test\r\n<\/code><\/pre>\n<p>The recorded Rails 8 update had 16 conflicting paths. Its proposed <code>config\/application.rb<\/code> retained <code>load_defaults 7.2<\/code>, but omitted the fixture&#8217;s explicit Sidekiq adapter, Redis cache and New York time zone. Accepting that file wholesale would have removed application decisions unrelated to the framework version.<\/p>\n<p>The final fixture kept eight custom configuration files and accepted eight reviewed files, including expanded parameter filtering, setup code and generated public pages. The earlier 7.1 step also changed test exception handling to <code>:rescuable<\/code>. Before\/proposed copies and the final diff are included in the evidence, so those choices can be inspected.<\/p>\n<p>Run the suite separately to collect deprecations. The <a href=\"https:\/\/github.com\/rails\/rails\/blob\/v8.0.5.1\/railties\/lib\/rails\/commands\/app\/update_command.rb\" target=\"_blank\" rel=\"noopener\">update command silences Rails deprecators<\/a> while it runs.<\/p>\n<h2 id=\"fix-enum-definitions-while-the-earlier-release-can-warn\" style=\"scroll-margin-top: 128px;\">Fix enum definitions while the earlier release can warn<\/h2>\n<p>The fixture began with this declaration.<\/p>\n<pre style=\"overflow-x: auto; max-width: 100%;\"><code class=\"language-ruby\">enum status: { queued: 0, processed: 1 }, _prefix: true\r\n<\/code><\/pre>\n<p>Rails 7.2 emitted its enum deprecation warning. Rails 8.0 raised <code>ArgumentError: wrong number of arguments (given 0, expected 1..2)<\/code> when the model loaded. This replacement passed the stored-value, predicate and scope checks.<\/p>\n<pre style=\"overflow-x: auto; max-width: 100%;\"><code class=\"language-ruby\">enum :status, { queued: 0, processed: 1 }, prefix: true\r\n<\/code><\/pre>\n<p>The <a href=\"https:\/\/github.com\/rails\/rails\/pull\/41328\" target=\"_blank\" rel=\"noopener\">positional form arrived in Rails 7.0<\/a>, so this repair can precede the Rails 8 deployment. Keep <code>queued<\/code> mapped to <code>0<\/code> and <code>processed<\/code> to <code>1<\/code>; changing those values would reinterpret stored rows. Rails 8 still accepts <a href=\"https:\/\/github.com\/rails\/rails\/pull\/53408\" target=\"_blank\" rel=\"noopener\">keyword labels after the positional name<\/a> and keyword options. A blanket instruction to remove all enum keyword arguments would be wrong.<\/p>\n<h2 id=\"test-the-defaults-that-can-change-an-otherwise-green-suite\" style=\"scroll-margin-top: 128px;\">Test the defaults that can change an otherwise green suite<\/h2>\n<p>Changing only <code>config.load_defaults 7.2<\/code> to <code>8.0<\/code> produced three failing assertions. Those failures exposed different behavior, not three framework defects. The fixture then adopted the new behavior deliberately and recorded the revised expectations.<\/p>\n<p>Ruby added <code>Regexp.timeout<\/code> in <a href=\"https:\/\/www.ruby-lang.org\/en\/news\/2022\/12\/25\/ruby-3-2-0-released\/\" target=\"_blank\" rel=\"noopener\">3.2, released in 2022<\/a>. Rails 8&#8217;s <a href=\"https:\/\/github.com\/rails\/rails\/blob\/v8.0.5.1\/railties\/lib\/rails\/application\/configuration.rb\" target=\"_blank\" rel=\"noopener\">defaults implementation<\/a> sets it to one second when the API exists and its value is nil. The fixture changed from nil to <code>1.0<\/code>. An independent check confirmed that an explicit <code>0.25<\/code> remained unchanged. Test the patterns your application runs; the global setting alone does not measure their cost.<\/p>\n<p>The <a href=\"https:\/\/github.com\/rails\/rails\/pull\/52091\" target=\"_blank\" rel=\"noopener\">time-conversion change<\/a> preserves the zone instead of just its current UTC offset. In the fixture, a January value in <code>America\/New_York<\/code> was converted with <code>to_time<\/code>, then advanced by 180 days. Retained defaults kept the offset at <code>-05:00<\/code>; 8.0 defaults produced <code>-04:00<\/code> in summer. That is useful daylight-saving behavior, but code expecting a fixed offset needs attention. No stored database timestamp was rewritten.<\/p>\n<p>The <a href=\"https:\/\/github.com\/rails\/rails\/blob\/v8.0.5.1\/railties\/lib\/rails\/generators\/rails\/app\/templates\/config\/initializers\/new_framework_defaults_8_0.rb.tt\" target=\"_blank\" rel=\"noopener\">8.0 defaults initializer<\/a> also explains strict freshness. With both conditional headers present, <code>If-None-Match<\/code> takes precedence. A matching ETag and older <code>If-Modified-Since<\/code> previously entered the fixture controller&#8217;s render branch; strict freshness avoided it. Both full responses were 304 because Rack&#8217;s conditional middleware also participated. A status-only assertion would have missed the extra rendering work, so the test records a header set inside that branch.<\/p>\n<h2 id=\"params-expect-is-a-separate-request-handling-change\" style=\"scroll-margin-top: 128px;\">params.expect is a separate request-handling change<\/h2>\n<p>GitHub&#8217;s <a href=\"https:\/\/github.blog\/news-insights\/the-library\/public-key-security-vulnerability-and-mitigation\/\" target=\"_blank\" rel=\"noopener\">March 2012 incident report<\/a> described insufficient filtering of incoming attributes. Rails&#8217; <a href=\"https:\/\/rubyonrails.org\/2012\/3\/21\/strong-parameters\" target=\"_blank\" rel=\"noopener\">proposal that month<\/a> moved mass-assignment filtering toward controllers; strong parameters shipped with <a href=\"https:\/\/guides.rubyonrails.org\/4_0_release_notes.html#actionpack\" target=\"_blank\" rel=\"noopener\">Rails 4.0 in 2013<\/a>. The point was to decide which attributes a particular request may set.<\/p>\n<p>Rails 8&#8217;s <a href=\"https:\/\/github.com\/rails\/rails\/pull\/51674\" target=\"_blank\" rel=\"noopener\"><code>expect<\/code> change<\/a> also checks the declared parameter shape. The fixture first retained this working filter.<\/p>\n<pre style=\"overflow-x: auto; max-width: 100%;\"><code class=\"language-ruby\">params.require(:shipment).permit(:status)\r\n<\/code><\/pre>\n<p>It then adopted this version in a separate commit.<\/p>\n<pre style=\"overflow-x: auto; max-width: 100%;\"><code class=\"language-ruby\">params.expect(shipment: [:status])\r\n<\/code><\/pre>\n<p>A valid shipment hash still returned 201. A scalar or array in place of that hash previously raised <code>NoMethodError<\/code> in the test environment; after the change each returned 400. An absent root returned 400 both before and after. That is a specific request-handling improvement, not a prerequisite for booting Rails 8.<\/p>\n<p>Review other shapes individually. The <a href=\"https:\/\/github.com\/rails\/rails\/blob\/v8.0.5.1\/actionpack\/lib\/action_controller\/metal\/strong_parameters.rb\" target=\"_blank\" rel=\"noopener\">tagged API<\/a> uses double arrays for an array of parameter hashes. It requires the declared root, not every permitted field inside it. Replacing an optional <code>fetch(:filters, {}).permit(...)<\/code> with <code>expect<\/code> would also reject an absent filters root. The fixture exercised the shipment cases; it does not certify every controller conversion.<\/p>\n<h2 id=\"the-asset-and-job-backends-have-separate-histories\" style=\"scroll-margin-top: 128px;\">The asset and job backends have separate histories<\/h2>\n<p><a href=\"https:\/\/guides.rubyonrails.org\/3_1_release_notes.html#assets-pipeline\" target=\"_blank\" rel=\"noopener\">Sprockets entered Rails 3.1 in 2011<\/a>, bringing asset organization and processing into the framework. <a href=\"https:\/\/rubyonrails.org\/2017\/4\/27\/Rails-5-1-final\" target=\"_blank\" rel=\"noopener\">Rails 5.1 in 2017<\/a> offered Webpacker alongside that pipeline. <a href=\"https:\/\/rubyonrails.org\/2021\/12\/15\/Rails-7-fulfilling-a-vision\" target=\"_blank\" rel=\"noopener\">Rails 7.0 in 2021<\/a> made browser import maps a default JavaScript path without requiring a Node build. These steps left applications with different manifests, processors and JavaScript dependencies.<\/p>\n<p>The <a href=\"https:\/\/rubyonrails.org\/2024\/11\/7\/rails-8-no-paas-required\" target=\"_blank\" rel=\"noopener\">Rails 8 announcement in 2024<\/a> made Propshaft the new default while explicitly retaining Sprockets support for existing applications. That supports keeping a compatible Sprockets setup during this hop. It does not establish that an old processor, removed gem API or untested manifest will still compile.<\/p>\n<p>Here, Sprockets Rails 3.5.2 compiled the assets on both ends of the upgrade. The final production Rack stack returned the fingerprinted CSS with status 200, the expected content type and a body matching the compiled file.<\/p>\n<p><a href=\"https:\/\/rubyonrails.org\/2014\/12\/19\/Rails-4-2-final\" target=\"_blank\" rel=\"noopener\">Active Job arrived in Rails 4.2 in 2014<\/a> with a common interface to job backends. <a href=\"https:\/\/guides.rubyonrails.org\/5_2_release_notes.html#redis-cache-store\" target=\"_blank\" rel=\"noopener\">Rails 5.2 in 2018<\/a> added its built-in Redis cache store. Rails 8&#8217;s database-backed Solid defaults pursue a different operational arrangement with fewer separate services. A team already operating Sidekiq and Redis must still account for retry behavior, queue delivery, cache eviction and connection capacity before changing those backends. Preserving them through the framework hop makes those later comparisons easier to interpret.<\/p>\n<h2 id=\"what-to-do-this-week\" style=\"scroll-margin-top: 128px;\">What to do this week<\/h2>\n<ol>\n<li>Establish a passing source-version baseline, then make the required dependency changes visible before the Rails bump.<\/li>\n<li>Fix removed APIs and review app:update conflicts. Keep your queue, cache, assets, authentication and deployment configuration explicit.<\/li>\n<li>Enable the reviewed 8.0 defaults with tests for the behaviors your application uses. Retain the old\/default comparisons in the upgrade record.<\/li>\n<li>Rehearse deployment and rollback with your own stored data and worker processes. This sample does not test your application&#8217;s migrations or a mixed-version rollout.<\/li>\n<li>Continue through the <a href=\"https:\/\/www.allerin.com\/services\/rails-upgrades#hop-8-0\">8.0 to 8.1 upgrade path<\/a>. The checkpoint is useful only if the supported destination is part of the work.<\/li>\n<\/ol>\n<p>The <a href=\"https:\/\/www.allerin.com\/rails-checks\/rails-7-2-to-8-0-2026-09.zip\">fixture download<\/a> provides source, lockfiles, recorded changes and reproduction instructions without registration. Research and execution were checked on <strong>7 September 2026<\/strong>, using released tags. The environment used Ruby 3.3.12, Sidekiq 7.3.10, Redis client 5.4.1 and Redis server 8.0.2. Tests covered selected authentication flows, Redis cache reads and writes with a positive TTL, actual throttling, plus the behaviors discussed here. They did not establish retry guarantees, a production security audit or mixed-version deployment safety.<\/p>\n<p><a href=\"https:\/\/www.allerin.com\/services\/rails-upgrades\">Allerin&#8217;s Rails upgrade work<\/a> starts with the code, runtime and behavior the application actually has.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A generated Rails 7.0 application carried through 7.2 to 8.0 shows which code and defaults need attention while its asset pipeline, jobs, cache and authentication stay in place.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[2037],"tags":[2053,2050,2038,16,2052,2051],"class_list":["post-14866","post","type-post","status-publish","format-standard","hentry","category-ruby-on-rails","tag-devise","tag-rails-8","tag-rails-upgrades","tag-ruby","tag-sidekiq","tag-sprockets"],"_links":{"self":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/14866","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/comments?post=14866"}],"version-history":[{"count":6,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/14866\/revisions"}],"predecessor-version":[{"id":14971,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/14866\/revisions\/14971"}],"wp:attachment":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/media?parent=14866"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/categories?post=14866"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/tags?post=14866"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}