1"use strict";(self.webpackChunkgatsby_starter_default=self.webpackChunkgatsby_starter_default||[]).push([[3148],{67646:function(e,n,t){t.r(n),t.d(n,{Head:function(){return b},default:function(){return v}});var a=t(28453),s=t(96540);function o(e){const n=Object.assign({h2:"h2",a:"a",span:"span",p:"p",ol:"ol",li:"li",strong:"strong",ul:"ul",h3:"h3"},(0,a.R)(),e.components);return s.createElement(s.Fragment,null,s.createElement(n.h2,{id:"introduction",style:{position:"relative"}},s.createElement(n.a,{href:"#introduction","aria-label":"introduction permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Introduction"),"\n",s.createElement(n.p,null,"In software development,\nthe evolution of applications is inevitable.\nAs your project grows\nand\nadapts to changing requirements,\ndatabase migrations become crucial to maintaining data integrity\nand\nstructural consistency.\nHowever,\nmanaging migrations effectively can be daunting,\nespecially as your application scales.\nThis is where tools like the\n",s.createElement(n.a,{href:"https://github.com/ankane/strong_migrations"},"Strong Migrations"),"\ngem come into play,\noffering a robust solution to streamline the migration process\nand\nensure database changes are implemented smoothly."),"\n",s.createElement(n.h2,{id:"what-is-strong-migrations",style:{position:"relative"}},s.createElement(n.a,{href:"#what-is-strong-migrations","aria-label":"what is strong migrations permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"What is Strong Migrations?"),"\n",s.createElement(n.p,null,s.createElement(n.a,{href:"https://github.com/ankane/strong_migrations"},"Strong Migrations"),"\nis a Ruby gem designed to help Rails developers perform safe\nand\nefficient database migrations,\nespecially in production environments.\nIt provides tools\nand\nbest practices to ensure migrations are performed smoothly\nwithout disrupting the application's availability."),"\n",s.createElement(n.h2,{id:"why-are-strong-migrations-important",style:{position:"relative"}},s.createElement(n.a,{href:"#why-are-strong-migrations-important","aria-label":"why are strong migrations important permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Why are Strong Migrations Important?"),"\n",s.createElement(n.ol,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Safety Nets:"),"\nStrong Migrations introduces safety checks to prevent\npotentially destructive operations from\ninadvertently being executed on your production database.\nAnalyzing your migration files can detect unsafe operations,\nsuch as irreversible data changes\nor\nlong-running queries,\nalerting you to potential issues before they cause harm."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Performance Optimization:"),"\nIn large-scale applications,\npoorly optimized migrations can lead to\nsignificant downtime during deployment.\nStrong Migrations helps optimize migration performance\nby identifying inefficient queries\nand\nsuggesting improvements,\nensuring database changes are applied swiftly\nand\nseamlessly."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Data Integrity:"),"\nEnsuring data integrity is paramount\nwhen making structural changes to your database.\nStrong Migrations provides tools to validate\nthe consistency of your data both before\nand\nafter migrations,\nminimizing the risk of corruption\nor\nloss."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Compliance:"),"\nIn regulated industries where compliance with data protection laws is mandatory,\nStrong Migrations helps enforce best practices\nand\nensures that migrations adhere to regulatory requirements.\nThis can be especially valuable for\napplications handling sensitive user information."),"\n"),"\n"),"\n",s.createElement(n.h2,{id:"how-to-use-strong-migrations",style:{position:"relative"}}
1,s.createElement(n.a,{href:"#how-to-use-strong-migrations","aria-label":"how to use strong migrations permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"How to Use Strong Migrations"),"\n",s.createElement(n.p,null,"Using Strong Migrations in your Rails application is straightforward.\nFirst,\nadd the gem to your Gemfile:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby">gem <span class="token string-literal"><span class="token string">\'strong_migrations\'</span></span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"Then,\nrun the following command to install it:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">bundle <span class="token function">install</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"Once the gem is installed,\nyou can use its features in your migrations.\nFor example,\nto add a column with a default value,\nuse the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">add_column</code>'}})," method with the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">default</code>'}})," option:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">AddDefaultValueToColumn</span> <span class="token operator"><</span> ActiveRecord<span class="token double-colon punctuation">::</span>Migration<span class="token punctuation">[</span><span class="token number">6.0</span><span class="token punctuation">]</span>\n <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">change</span></span>\n add_column <span class="token symbol">:table_name</span><span class="token punctuation">,</span> <span class="token symbol">:column_name</span><span class="token punctuation">,</span> <span class="token symbol">:string</span><span class="token punctuation">,</span> <span class="token symbol">default</span><span class="token operator">:</span> <span class="token string-literal"><span class="token string">\'default_value\'</span></span><span class="token punctuation">,</span> <span class="token symbol">null</span><span class="token operator">:</span> <span class="token boolean">false</span>\n <span class="token keyword">end</span>\n<span class="token keyword">end</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"To perform potentially dangerous operations,\nsuch as dropping a column,\nuse the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">safety_assured</code>'}})," method to turn off safety checks temporarily."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">RemoveColumnFromTable</span> <span class="token operator"><</span> ActiveRecord<span class="token double-colon punctuation">::</span>Migration<span class="token punctuation">[</span><span class="token number">6.0</span><span class="token punctuation">]</span>\n <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">change</span></span>\n safety_assured <span class="token punctuation">{</span> remove_column <span class="token symbol">:table_name</span><span class="token punctuation">,</span> <span class="token symbol">:column_name</span> <span class="token punctuation">}</span>\n <span class="token keyword">end</span>\n<span class="token keyword">end</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"Finally,\nwhen running migrations in a production environment,\nuse the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">safety_assured</code>'}})," method to ensure that the migration is safe to run:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token assign-left variable">RAILS_ENV</span><span class="token operator">=</span>production bundle <span class="token builtin class-name">exec</span> rails db:migrate</code></pre></div>'}}),"\n",s.createElement(n.h2,{id:"dangerous-operations",style:{position:"relative"}}
1,s.createElement(n.a,{href:"#dangerous-operations","aria-label":"dangerous operations permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Dangerous Operations"),"\n",s.createElement(n.p,null,"The following operations can cause downtime or errors:"),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,"Adding a column with a non-null default value to an existing table"),"\n",s.createElement(n.li,null,"Removing a column"),"\n",s.createElement(n.li,null,"Changing the type of a column"),"\n",s.createElement(n.li,null,"Setting a NOT NULL constraint with a default value"),"\n",s.createElement(n.li,null,"Renaming a column"),"\n",s.createElement(n.li,null,"Renaming a table"),"\n",s.createElement(n.li,null,"Creating a table with the force option"),"\n",s.createElement(n.li,null,"Adding an index non-concurrently (Postgres only)"),"\n",s.createElement(n.li,null,"Adding a JSON column to an existing table (Postgres only)"),"\n"),"\n",s.createElement(n.p,null,"Let's go over an example to understand the flow."),"\n",s.createElement(n.h3,{id:"adding-a-column-with-a-non-null-default-value",style:{position:"relative"}},s.createElement(n.a,{href:"#adding-a-column-with-a-non-null-default-value","aria-label":"adding a column with a non null default value permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Adding a column with a non-null default value"),"\n",s.createElement(n.p,null,"Let's say you have a User model\nand\nwant to add a new column with a default value.\nYou will write a migration as follows."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">AddStatusToUsers</span> <span class="token operator"><</span> ActiveRecord<span class="token double-colon punctuation">::</span>Migration<span class="token punctuation">[</span><span class="token number">7.1</span><span class="token punctuation">]</span>\n <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">change</span></span>\n add_column <span class="token symbol">:users</span><span class="token punctuation">,</span> <span class="token symbol">:status</span><span class="token punctuation">,</span> <span class="token symbol">:text</span><span class="token punctuation">,</span> <span class="token symbol">default</span><span class="token operator">:</span> <span class="token string-literal"><span class="token string">\'on_boarded\'</span></span>\n <span class="token keyword">end</span>\n<span class="token keyword">end</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"In previous iterations of Postgres,\nintroducing a column with a default value to an already-existing table\nwould prompt a complete rewrite of the entire table,\nresulting in blockage for both reading\nand\nwriting operations in Postgres."),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"NOTE:"),"\nIn Postgres 11+,\nthis no longer requires a table rewrite\nand\nis safe."),"\n",s.createElement(n.p,null,"If you try to run the above migration,\nstrong migrations will raise an error as below:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">rake aborted!\nStandardError: An error has occurred, all later migrations canceled:\n\n=== Dangerous operation detected #strong_migrations ===\n\nAdding a column with a non-null default causes the entire table to be rewritten.\nInstead, add the column without a default value, then change the default.\n\nclass AddStatusToUsers < ActiveRecord::Migration[7.1]\n def up\n add_column :users, :status, :text\n change_column_default :users, :status, \'on_boarded\'\n end\n\n def down\n remove_column :users, :status\n end\nend</code></pre></div>'}}),"\n",s.createElement(n.h3,{id:"migration-timeouts",style:{position:"relative"}}
1,s.createElement(n.a,{href:"#migration-timeouts","aria-label":"migration timeouts permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Migration Timeouts"),"\n",s.createElement(n.p,null,"The ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">strong_migrations</code>'}})," gem in Ruby on Rails\nalso provides functionality to set timeouts for migrations.\nThis is crucial in preventing migrations\nfrom causing extended downtime in production environments.\nSetting timeouts ensures that migrations are complete\nwithin a reasonable time frame,\npreventing situations where they may block database operations\nfor an extended period."),"\n",s.createElement(n.p,null,"You can set a timeout for migrations globally in your Rails application.\nAdd the following configuration to an initializer file\n(e.g., ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/initializers/strong_migrations.rb</code>'}}),"):"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby">StrongMigrations<span class="token punctuation">.</span>timeout <span class="token operator">=</span> <span class="token number">600</span> <span class="token comment"># Set timeout to 10 minutes (in seconds)</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"Adjust the timeout value according to your application's needs.\nThe example above sets the timeout to 600 seconds (10 minutes)."),"\n",s.createElement(n.p,null,"If a migration exceeds the specified timeout,\nstrong_migrations will automatically halt the migration\nand\nraise an error.\nThis prevents the migration from causing prolonged downtime."),"\n",s.createElement(n.p,null,"By configuring migration timeouts with the strong_migrations gem,\nyou can enforce time limits on database migrations,\nmitigating the risk of extended downtime\nand\nensuring the reliability of your application's deployment process."),"\n",s.createElement(n.h2,{id:"best-practices",style:{position:"relative"}},s.createElement(n.a,{href:"#best-practices","aria-label":"best practices permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Best Practices"),"\n",s.createElement(n.ol,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Regularly Update Gem:"),"\nStay updated with the latest version of Strong Migrations\nto leverage new features,\nbug fixes,\nand\nsecurity patches.\nRegular updates ensure that your migrations remain robust\nand\naligned with best practices."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Run Checks Locally:"),"\nBefore deploying migrations to production,\nrun Strong Migrations checks locally\nto catch any potential issues early in the development cycle.\nThis proactive approach helps in resolving issues\nbefore they impact your production environment."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Review Migration Plans:"),"\nReview migration plans carefully,\nespecially for complex schema changes\nor\nlarge datasets.\nConsider breaking down migrations into smaller,\nmanageable steps to minimize the risk of downtime\nand\noptimize performance."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Monitor Performance:"),"\nMonitor the performance of your migrations\nin production environments using tools like database monitoring\nand\nlogging.\nIdentify any bottlenecks\nor\nperformance issues\nand\noptimize your migrations accordingly."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Practice Safe Rollbacks:"),"\nAlways have a rollback plan in case of unexpected issues\nduring migration deployment.\nTest rollback procedures in staging\nor\ndevelopment environments to ensure a smooth recovery."),"\n"),"\n"),"\n",s.createElement(n.h2,{id:"conclusion",style:{position:"relative"}}
1,s.createElement(n.a,{href:"#conclusion","aria-label":"conclusion permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Conclusion"),"\n",s.createElement(n.p,null,"In the fast-paced world of software development,\neffective database migration management is essential\nfor maintaining your applications' stability,\nperformance,\nand\nintegrity.\nStrong Migrations empowers Rails developers\nwith the tools they need to confidently navigate\nthe complexities of migration management,\nproviding safety checks,\nperformance optimizations,\nand\ncompliance features to streamline the process\nand\nmitigate risks.\nBy incorporating Strong Migrations into your workflow,\nyou can ensure smooth,\nseamless migrations that pave\nthe way for the continued evolution of your applications."))}var l=function(e){void 0===e&&(e={});const{wrapper:n}=Object.assign({},(0,a.R)(),e.components);return n?s.createElement(n,e,s.createElement(o,e)):o(e)},r=t(5588),i=t(65427),c=t(20504),u=t(43397),m=t(61942);const p=e=>e.replace(/\/+$/,""),d=(e,n)=>n?""+e+(n.startsWith("/")?n:"/"+n):e,g=(e,n)=>d(p(e),n),h=(e,n)=>d((e=>"undefined"!=typeof window?window.location.origin:p(e))(e),n),y=(e,n)=>{const t=(0,r.d)(n);return t?g(e,t):(e=>g(e,"/shakacode-og.png"))(e)},f=e=>{let{data:n,location:t,children:a}=e;const{frontmatter:o}=n.mdx,{siteUrl:l}=n.site.siteMetadata,r=h(l,t.pathname);return s.createElement(s.Fragment,null,s.createElement(i.A,null),s.createElement(c.A,{header:s.createElement(m.r,{breadcrumb:o.title}),main:s.createElement(s.Fragment,null,s.createElement(m.c,{body:a,title:o.title,author:o.author,date:o.date,link:r,categories:o.categories,featuredImage:o.featuredImage,showFeaturedImage:o.showFeaturedImage}),s.createElement(u.LN,null))}))};function v(e){return s.createElement(f,e,s.createElement(l,e))}const b=e=>{let{data:n,location:t}=e;const{frontmatter:a,excerpt:o}=n.mdx,{siteMetadata:l}=n.site,{siteUrl:r,title:i,description:c}=l,u=((e,n,t)=>e.excerpt||n||t)(a,o,c),m=y(r,a.featuredImage),p=g(r,t.pathname);return s.createElement(s.Fragment,null,s.createElement("title",null,a.title+" | "+i),s.createElement("link",{rel:"canonical",href:p}),s.createElement("meta",{name:"description",content:u}),s.createElement("meta",{property:"og:title",content:a.title}),s.createElement("meta",{property:"og:description",content:u}),s.createElement("meta",{property:"og:type",content:"article"}),s.createElement("meta",{property:"og:url",content:p}),s.createElement("meta",{property:"og:image",content:m}),s.createElement("meta",{name:"image",content:m}),s.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),s.createElement("meta",{name:"twitter:title",content:a.title}),s.createElement("meta",{name:"twitter:description",content:u}),s.createElement("meta",{name:"twitter:image",content:m}))}}}]); 2//# sourceMappingURL=component---src-template-blog-article-tsx-content-file-path-src-posts-keeping-your-database-migrations-strong-with-strong-migrations-gem-index-mdx-b2b1f0b9abbfe36d627d.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.