一年前我绝对做不到这一点,但现在我终于开发出了我的第一个 Web 应用。就在这里!

2025-06-07

一年前我绝对做不到这一点,但现在我终于开发出了我的第一个 Web 应用。就在这里!

大约一年前,我index.html在 Atom 编辑器中创建了一个文件,输入内容"Hello, World!",启动httpserver,然后第一次在浏览器中看到它渲染出来。从那一刻到今天,我一直在学习 Ruby、SQL、HTML、CSS 和 JavaScript。我失败的次数比成功的次数多,但我比以往任何时候都更快乐。总之,今天的失败弥补了过去的失败,因为(多亏了它们)我刚刚完成了我的第一个完整的 Web 应用的构建。

概念

当我在思考要建造什么的时候,我牢记了

[已删除用户] 图片

[已删除用户]

他曾经告诉我,要保持简单,尤其是在第一次建造东西的时候。“你的目标是学习,”他说,“而不是给人留下深刻印象;再说,对于你这个水平的人来说,做好简单的项目就已经很令人印象深刻了。”

鉴于此,我知道我的应用只需要 has_many/belongs_to 关系,别无其他。两个模型,没有连接表,没问题。这意味着我会有一个 User 模型和一个属于 User 的模型。所以我觉得葡萄酒日志特别适合这个。用户has_many葡萄酒,以及 Wine belongs_toUser。用户可以输入他们喜欢的葡萄酒信息,并存储起来以备将来参考。简直完美!

然而,尽管我承诺要保持简洁,但我却很难对这个想法感到兴奋。一个想法不断浮现在我的脑海里:让所有用户都能查看所有葡萄酒条目,而不仅仅是他们自己的。不久之后,我就有了打造一个以葡萄酒为中心的社交媒体平台的想法。一旦我把它命名为Vino,就再也没有回头路了。

第一天:测试

我知道我想用测试驱动的方式构建 Vino,这当然意味着我需要先写测试。问题是我不知道怎么写测试。但我知道如何阅读测试,所以我觉得现在是学习如何写测试的好时机。

我首先规划了项目的基本结构。我拿出一张纸,草草地写下了七条 RESTful 路由、它们对应的视图以及每个视图包含的内容,然后我对用户从登录到退出如何与 Vino 进行交互有了基本的了解。

作为一名前厨师,我习惯向前辈学习。厨师,尤其是在开发初期,会研究并使用根据自身需求调整的菜谱。随着实践的深入,他们对菜谱的依赖会越来越少。这与我决定学习如何编写测试的方式类似。我搜索了我在 GitHub 上 fork 的仓库,直到找到 RSpec 和 Capybara 测试的优秀示例。我将它们复制到我的 spec 文件中,逐行检查,并根据我对应用程序的期望进行重写。最终,我的测试套件中包含了 42 个测试。它们包含针对两种模型的测试,用于验证它们是否具备我所需的属性;其余的是应用程序控制器测试,涵盖了从用户登录到无法破解 URL 和修改其他用户数据的所有内容。编写测试需要一整天的时间,但我深入了解了测试的工作原理和编写方法,这使得 Vino 的构建过程变得更加高效。

第二天到第三天:关系

测试写好后,我对构建项目更有信心了,因为我已经习惯了运行测试和调试。我首先运行模型规范,定义类,并为 User 模型和 Wine 模型编写迁移文件。完成后,就该运行应用程序控制器规范并定义路由了。我非常喜欢数据库,但当你开始定义路由时,你才真正开始深入研究并弄清楚逻辑。这正是我编程时最渴望的事情,所以我非常享受通过调试来让应用程序正常运行的过程。

Pry 是我最好的朋友。由于我用的是 Sinatra 构建的,所以我还大量使用了一个名为 Tux 的 gem,当你bundle exec tux在控制台中运行它时,它会打开一个交互式环境,就像 Pry 和 IRB 的结合体一样。

不久之后,所有测试都通过了,数据也恢复正常。我的应用运行起来了!

不幸的是,它也丑陋得像罪过。

第四天至第七天:HTML 探险

我希望Vino看起来漂亮。对我来说,即使我尽可能地保持了它的朴素,也要让它成为一件值得骄傲的东西。一件我可以指着它毫不尴尬地说“这是我做的”的东西。我差点就成功了。

我的设计技能有限,但我仍然希望应用程序保持简洁。因此,我决定用 Bootstrap 来构建,而不是从头开始编写所有 HTML 和 CSS。这样做有几个好处。首先,这意味着我可以使用一个简单的 Bootstrap 模板(我没有使用主题),并编写大量的自定义 HTML 和 CSS,而不必担心诸如清除修复之类的问题。所有部分都能很好地组合在一起,只要我注意网格布局,不要弄乱行列的大小。这意味着我不必担心应用程序的响应式设计,因为它会自动响应。这也意味着我可以使用 Bootstrap 的 JavaScript 为 Vino 提供一些不错的功能,而这些功能我通常不会在学习的这个阶段尝试自己添加。例如,我使用了很多模态框来实现不同的功能,我可以用 HTML 编写它们,再用 CSS 设置样式,它们就能正常工作了。

为了学习如何做到这一点,我学习了w3schools.com上的一个教程,它指导我如何添加 BootstrapCDN 脚本,并为一个社交媒体风格的网站构建一个基本的网格。我根据自己的需求对网格进行了一些修改,然后开始设计样式。我觉得让它看起来像 Facebook 会很有趣,所以我编写了 CSS 来实现它,每当遇到问题时,我就去 Google 上搜索。

彼得·格里芬感到沮丧

这听起来可能很容易,但我的第一次尝试却惨败了。当我尝试为每条葡萄酒条目创建卡片之类的操作时,错误接踵而至,而且每当我修复一个错误,另一个错误就会在其他地方出现。这就像我玩过的最糟糕的打地鼠游戏一样。我的修改已经深入到兔子洞深处,我知道我需要重新开始。于是,我运行了git checkout,创建了一个新分支,并开始重建 HTML。经过一两天的努力,我终于得到了一个我喜欢的布局,而且它运行正常。

git checkout master
git merge revised-layout

当我对每个细节都感到满意时,我开始重构代码。我努力让它尽可能地遵循DRY原则,并开始删掉那些一开始有用但在最终产品中毫无用处的代码。我努力避免不必要的重复。在构建代码时,每个视图的所有HTML和CSS都放在各自的.erb文件中。我把所有CSS都移到样式表中,并将尽可能多的重复HTML移到布局文件中。它绝对可以更加DRY,但我在经验不足的情况下已经尽力了。当我想到自己还需要做什么时,我松了一口气。至少目前是这样。

git add .
git commit -m "done."
git push

我微笑着打开一瓶酒,给自己倒了一杯,然后坐了下来……

...然后查看标签,启动shotgun,登录,并将其放入我的应用程序中。

下一步

我想添加一些功能,比如评论功能,这样可以很好地整合多对多关系或 has_many 直通关系。我还想添加更严格的身份验证、闪现消息、使用 Facebook OAuth 登录等等。下一步我想构建一个 Rails 应用,所以我可能会用 Rails 重新构建 Vino 并添加这些功能。

编程有时会让人沮丧,以至于我想去做点别的事情。然后我做了一些东西,想起我有多爱它。我希望我总能找到办法重新爱上编程。

如果您愿意,可以查看GitHub repo

文章来源:https://dev.to/jeremy/a-year-ago-i-never-would-have-been-able-to-do-this-but-i-just-built-my-first-web-app-here-it-is-1534
PREV
实时编码入门
NEXT
你应该知道的数组技巧和窍门