rails 修改迁移文件_Rails应对迁移:向后兼容。 第1部分

rails 修改迁移文件

付费客户,向后兼容和重构 (Paying customers, backwards compatibility and refactoring)

Recently, I agreed to do some work for a fast growing startup. This company and their web application has been active over 2 years, boasting a handful of developers and a sizable amount of early round funding.

最近,我同意为快速成长的创业公司做一些工作。 该公司及其Web应用程序已经运行了2年多,拥有众多开发人员和大量的早期融资。

We’re not talking enterprise level but the codebase is well beyond a hobbyist project. Zipped the codebase is over 50MB, unzipped over 300MB of tightly wound business logic, duplication and tech debt. But let’s not overlook the fact that this application is in production, and big name clients rely on and (most importantly) pay for its features.

我们不是在谈论企业级别,但是代码库远远超出了业余项目。 压缩后的代码库超过50MB,解压缩了超过300MB的紧密缠绕的业务逻辑,重复和技术债务。 但是,请不要忽视这个应用程序正在生产中的事实,大牌客户依靠它(并且最重要的是)为其功能付费。

Paying customers don’t care about an application’s tech debt, testing coverage or using the latest frameworks. They want good software today, not perfect software tomorrow.

支付 çustomers不关心应用的高科技债务,测试覆盖范围或使用最新的框架。 他们今天想要好的软件,而不是明天的完美软件。

目标:翻录前端! 我的意思是“迁移”前端。 (Objective: Ripping out the Frontend! I mean, “migrating” the Frontend.)

It was immediately clear to me, and other engineers on the team that the greatest need was to separate the Front and Back end codebases. So that’s what I set out to accomplish, with a couple goals to keep in mind.

我和团队中的其他工程师立即很清楚,最需要的是分离前端和后端代码库。 这就是我要完成的目标,并牢记一些目标。

  1. Backwards compatibility: The existing website had to continue serving customer’s needs. No closing up shop for 3 months to rebuild everything.

    向后兼容性:现有网站必须继续满足客户的需求。 3个月没有关闭商店来重建一切。
  2. Piece by Piece: A refactor of this magnitude could only be accomplished little by little.

    逐个片段:如此庞大的重构只能一点一点地完成。
  3. Use existing Backend: create new JSON API endpoints to run alongside traditional controllers.

    使用现有的后端:创建新的JSON API终结点以与传统控制器一起运行。
  4. Abstract Components: Refactor Frontend HTML/ERB templates into React components.

    抽象组件:将前端HTML / ERB模板重构为React组件。
  5. End goal: full transition to distinct React Frontend. Move templates and features slowly into a new React app that will eventually entirely replace the previous MVC Frontend.

    最终目标:完全过渡到独特的React Frontend。 将模板和功能缓慢移动到新的React应用中,该应用最终将完全取代以前的MVC前端。
  6. Have fun.

    玩得开心。

In my 9 – 5 grind, I’m a Frontend developer, but I have had a few years of experience working with Ruby on Rails backends. I was not prepared for the black hole of code this startup had amassed.

在9到5分的工作中,我是Frontend开发人员,但是我有几年使用Ruby on Rails后端的经验。 我没有为这个初创公司积累的代码黑洞做好准备。

I won’t even mention the backend language or framework, because frankly to this day I still don’t understand how it worked. And you know what? I’m at peace with that. The principles I learned while taking this project on could be applied to any MVC web application migrating to an independent Frontend. For the sake of this article and my sanity, I will code the Backend examples in Ruby, and Frontend examples in React.

我什至不会提到后端语言或框架,因为坦率地说,直到今天,我仍然不知道它是如何工作的。 你知道吗? 我很安心。 我在从事该项目时学到的原理可以应用于任何迁移到独立前端的MVC Web应用程序。 为了本文和我的理智,我将在Ruby中编写Backend示例,在React中编写Frontend示例。

Side note: There are dozens of ways to refactor, your situation and code will differ from mine. This series is not a step by step guide on how to migrate any Rails MVC to a React Frontend. React on Rails and React Rails are fantastic gems available to Rails projects to accomplish what this article describes.

旁注:有多种重构方法,您的情况和代码将与我的有所不同。 本系列文章不是有关如何将任何Rails MVC迁移到React Frontend的逐步指南。 React on RailsReact Rails是Rails项目可用来完成本文所述内容的绝妙宝石。

让我们见识一下我们花哨的(笨重的)MVC应用程序 (Let’s meet our fancy (clunky) MVC app)

Code for this project is available on my github.

这个项目的代码可以在我的github上找到

Image for post

Our example app for this article is: Car Finder!! It’s not cutting edge. And it sure isn’t powered by AI, or Blockchain. But for our purposes, this should work just fine.

我们本文的示例应用程序是:Car Finder! 这不是最前沿的。 而且它肯定不是由AI或Blockchain驱动的。 但是出于我们的目的,这应该可以正常工作。

The main thing going on in this app is a some sweet 90’s style CSS, hacked together by someone who got fired long ago. First we see a Car Hero, welcoming us to the MVC Car Finder. On the left side is our Featured Cars List. Finally we have our All Cars List list of all the cars. At the moment this app is completely MVC. All of this has been generated with ERB/HTML templates, no JS.

该应用程序中主要发生的事情是90年代风格甜美CSS,由很久以前被炒鱿鱼的人砍死了。 首先,我们看到一个汽车英雄,欢迎我们使用MVC汽车搜索器。 左侧是我们的精选 汽车清单 。 最后,我们有所有汽车的“ 所有汽车列表”列表。 目前,该应用程序完全是MVC。 所有这些都是使用ERB / HTML模板(没有JS)生成的。

So let’s dive into the code.

因此,让我们深入研究代码。

后端(M):Ruby模型 (Backend (M): Ruby Models)

Our car.rb model has several database backed attributes, name, make, style, year, price_min, price_max and color. We included a helper method: featured_cars() to return a list of featured cars.

我们的car.rb模型具有多个数据库支持的属性,包括name, make, style, year, price_min, price_maxcolor. 我们包括了一个辅助方法: featured_cars()以返回特色汽车列表。

version 1 MVC model: car.rb
版本1 MVC模型:car.rb

后端(C):Ruby控制器 (Backend (C): Ruby controllers)

Our cars_controller.rb contains an index action, where an instances variables are set that will later be used in the template to render our Featured Cars List and All Cars List.

我们的cars_controller.rb包含一个index动作,在该动作中设置了一个实例变量,该变量随后将在模板中用于呈现“ 精选汽车列表”和“ 所有汽车列表”。

version 1 MVC controller: cars_controller.rb
版本1 MVC控制器:cars_controller.rb

前端(V):ERB / HTML模板 (Frontend (V): ERB/HTML Templates)

Our Frontend is generated by Rails ERB/HTML templates. Notice the Rails partial CarsHero being used in an attempt to stay dry and organize our app into components. Then our code iterates over the @all_cars and @featured_cars lists to render blocks of HTML. And people say that HTML isn’t real programming!

我们的前端是由Rails ERB / HTML模板生成的。 请注意,正在使用Rails的CarsHero 部分 ,以保持干燥并将我们的应用程序组织成组件。 然后,我们的代码遍历@all_cars@featured_cars列表以呈现HTML块。 人们说HTML不是真正的编程!

在MVC中注入React,就像真实注入一样痛苦 (Injecting React in MVC, as painful as real injection)

Before we continue, it’s necessary to go on a small tangent to explain why integrating React into an existing MVC app is such a pain. In a perfect world we’d spark up a new React app with a nifty new framework like Gatsby.js, or Next.js, and our MVC app could just import a couple JS files from localhost and Bam! Everything works. Reality is much different. Building a React bundle requires a lot of work adding dependencies, transpiling JS for browsers, often even compiling images and stylesheets into JS.

在继续之前,有必要进行一点切线解释,为什么将React集成到现有的MVC应用程序中是如此痛苦。 在理想的情况下,我们将使用Gatsby.js或Next.js等漂亮的新框架来启动一个新的React应用程序,而我们的MVC应用程序只需从本地主机和Bam导入几个JS文件即可! 一切正常。 现实大不相同。 构建React包需要大量工作来添加依赖项,为浏览器转换JS,甚至将图像和样式表编译为JS。

This process of selecting a React framework and reverse engineering its build files to be used in your MVC app will require a lot of up front work. But it will be worth in the end to have a stand alone React app.

选择一个React框架并对它的构建文件进行反向工程以在您的MVC应用程序中使用的过程将需要大量的前期工作。 但最终拥有一个独立的React应用程序将是值得的。

For this tutorial, we’re going with a more homemade, less scalable solution. We will be using the built in Rails webpacker gem. This solution involves very obvious tradeoff: we can get started right away creating components, but our one-off components can’t benefit from a full-feature React framework like Gatsby or Next.

在本教程中,我们将采用更加自制,扩展性较差的方法 解。 我们将使用内置的Rails Webpacker gem。 该解决方案涉及非常明显的折衷:我们可以立即开始创建组件,但是我们的一次性组件无法从Gatsby或Next等功能齐全的React框架中受益。

Rails 6和Modern JS (Rails 6 and Modern JS)

Rails has made significant improvements integrating with modern Frontend frameworks, out of the box, rails 6 includes the webpacker gem to easily incorporate modern js. As previously mentioned, react_on_rails and react-rails are great options that I would infinitely recommend over the approach covered in this article. But remember, in real life I wasn’t working with Rails.

Rails与现代的Frontend框架集成已经取得了显着的进步,Rails 6包含了webpacker gem,可以轻松地集成现代js。 如前所述, react_on_railsreact-rails是很棒的选择,对于本文涵盖的方法,我将无限推荐。 但是请记住,在现实生活中,我并没有与Rails合作。

With Rails, getting up and running with React is amazing easy, leveraging the built-in webpacker gem.

使用Rails,利用内置的webpacker gem可以轻松地启动和运行React。

$ bundle exec rails webpacker:install:react

This command will install React into our MVC, configure webpack to compile assets for React, and create a hello_world.jsx React Component. Let’s keep our new React components separate from any existing JS code in our MVC app, by creating new React components directory.

该命令将把React安装到我们的MVC中,配置webpack以便为React编译资产,并创建hello_world.jsx React组件。 通过创建新的React组件目录,让我们将新的React组件与MVC应用程序中的任何现有JS代码分开。

我们的第一个组件:CarHero.js (Our First Component: CarHero.js)

With React installed in our MVC app, we’re ready to create our React components and inject them into the existing HTML/ERB templates. Our CarHero Rails partial is a perfect candidate to be refactored into a new React Component.

在MVC应用程序中安装了React之后,我们就可以创建React组件并将它们注入到现有HTML / ERB模板中。 我们的CarHero Rails零件是重构到新的React组件的理想选择。

Create the CarHero.js React component, we can even create SASS styles and it will be compiled flawlessly by Rails. I ❤️ u rails.

创建CarHero.js React组件,我们甚至可以创建SASS样式,Rails会完美地对其进行编译。 我❤️u rails。

将CarHero注入我们的模板 (Injected CarHero into our Template)

With our CarHero.js component built, we need to prepare our HTML/ERB template to receive the React component. Let’s create a container inside of the HTML/ERB template where we want our component to be injected. We’ll add 2 important properties

构建好CarHero.js组件后,我们需要准备HTML / ERB模板以接收React组件。 让我们在HTML / ERB模板内部创建一个容器,在该容器中我们希望注入组件。 我们将添加2个重要属性

  1. class="react-component" so that we can search for it later with document.querySelectorAll('.react-component')

    class="react-component"以便我们稍后可以使用document.querySelectorAll('.react-component')

  2. data-component="CarHero" so that React knows the name of the component to render.

    data-component="CarHero"以便React知道要渲染的组件的名称。

Last step before that beautiful demo time, we have to write a simple JS script render the React components. Create a react_components_manifest.js pack, although you can name the script whatever you’d like.

在美丽的演示时间之前的最后一步,我们必须编写一个简单的JS脚本来渲染React组件。 创建react_components_manifest.js pack ,尽管您可以根据需要命名脚本。

$ touch app/javascript/packs/react_components_manifest.js

This script imports our dependencies and components, then adds a document.ready event to find all HTML elements with the react-component class. Then iterates on each DOM element, extracting the React Component that will be rendered from the data-component attribute. Finally we render the component into the DOM element with ReactDOM.render(React.createElement(<Component>, <domNode>))

此脚本导入我们的依赖项和组件,然后添加document.ready事件以查找带有react-component类的所有HTML元素。 然后,在每个DOM元素上进行迭代,提取将从data-component属性呈现的React Component。 最后,我们使用ReactDOM.render(React.createElement(<Component>, <domNode>))将组件渲染到DOM元素中

我们行动的第一要素 (Our First Component in Action)

Image for post

结论 (Conclusion)

And with that, we’ve enabled our MVC app to use injected React components. We’ve maintained backwards compatibility for our customers, and trail-blazed a path forward for our developers to build a service-based architecture. We will continue our migration by extracting the AllCars and FeaturedCars components from MVC into React, and even and an impromptu new search feature. Because no refactor would be complete without last minute product requirements.

至此,我们使MVC应用程序能够使用注入的React组件。 我们一直为客户保持向后兼容性,并为开发人员构建基于服务的体系结构开辟了一条前进的道路。 我们将通过从MVC中提取AllCarsFeaturedCars组件到React,甚至是即兴的新搜索功能中继续进行迁移 因为没有最后一刻的产品需求,重构就不会完成。

Thanks for reading, I hope you’ve learned something or at least laughed at my misfortunes.

感谢您的阅读,希望您学到了一些东西,或者至少对我的不幸笑了。

Any feedback would be greatly appreciated, or passive aggressively ignored.

任何反馈将不胜感激,或被动地积极地忽略。

ethanoz.com

ethanoz.com

翻译自: https://medium.com/swlh/rails-to-react-migration-backwards-compatibility-part-1-dc218b2766ea

rails 修改迁移文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值