<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>nuanshuidai (暖水袋)</title>
    <link>https://ruby-china.org/nuanshuidai</link>
    <description/>
    <language>en-us</language>
    <item>
      <title>请教，Rails 支持操作 word、excel 这些文档吗？</title>
      <description>&lt;p&gt;手头有个工作需要读写word和excel文档，包括格式、各种元素的操作。以前在c#下写过类似的功能，不知道Rails下可不可以完成？有经验的伙伴们给点帮助啊！谢谢！&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Wed, 19 Jun 2024 09:02:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/43753</link>
      <guid>https://ruby-china.org/topics/43753</guid>
    </item>
    <item>
      <title>C++“中年危机”有救了！C++ 之父新动作！</title>
      <description>&lt;p&gt;在不久前 TIOBE 发布的 10 月编程语言排行榜上，C++ 一举越过 Java，摘得探花位，仅次于 Python 和 C。年过四旬的 C++ 依然是全球最流行的编程语言之一，不过近年来一些巨头的动向也让 C++ 的安全性频频走向争议的中心。&lt;/p&gt;

&lt;p&gt;前有微软透露正基于 Rust 语言改写 Windows 11 内核，部分替代之前的 C++，后有谷歌声称正在将 Android 原生代码从 C++ 迁移到 Rust，从而进一步减少安全漏洞。&lt;/p&gt;

&lt;p&gt;就在外界纷纷揣测 C++ 如何应对突如其来的中年危机，是否真的应该让位于后起之秀时，近日 C++ 之父 Bjarne Stroustrup 在上个月举办的编程语言年度大会上公开表态：他将增加新的安全工具应对批评，为全球数十亿行 C++ 代码带来新的解决方案。&lt;/p&gt;

&lt;p&gt;对于那些认为问题出在 C++ 本身、解决方案是改用另一种语言的批评人士，这位已经 72 岁的大佬予以了驳斥。&lt;/p&gt;

&lt;p&gt;第一，安全性指的不仅仅是内存安全。&lt;/p&gt;

&lt;p&gt;第二，语言之间的互操作性需求往往会被忽视。&lt;/p&gt;

&lt;p&gt;第三，语言切换的成本通常会被低估。&lt;/p&gt;

&lt;p&gt;Stroustrup 首先指出“通常提到的安全性只是内存安全——这是不够的......与其他语言（包括 C++ 和 C）进行互操作的需求往往不会被提及。而且转换的成本可能非常高。这一点很少被提及......”&lt;/p&gt;

&lt;p&gt;“从我所看到的观点来看，我们将用大约 7 种不同的语言来取代 C++。也许在距今四十年后，我们可能会有 20 种不同的语言，它们必须相互操作。这将会很困难。”&lt;/p&gt;

&lt;p&gt;Stroustrup 还指出，“许多所谓的‘安全’语言将所有底层的东西都外包给了 C 或 C++”，暂时脱离原始语言来访问硬件资源，甚至操作系统 (通常是用 C 编写的)——甚至可能是极为古老的、藏在外部库中的“可信代码”……&lt;/p&gt;

&lt;p&gt;Stroustrup 把我们目前的情况称为“一种渐进式和进化式的方法，而不是一味追求全新的方法。”就像盖尔定律:“一个有效的复杂系统势必是从一个有效的简单系统发展而来的。”&lt;/p&gt;

&lt;p&gt;归根结底，就像 Stroustrup 所指出的，切换语言可能看起来是在构建一个新系统，但是想越过所有旧系统的问题来解决一切，只是一个幻想。切换语言所要付出的代价可能远比你理想中的要高。&lt;/p&gt;

&lt;p&gt;Stroustrup 提到了安全性的许多概念，重点介绍了资源泄漏、溢出、内存损坏、计时错误、并发错误、终止错误——当然还有类型错误。随后，他就 C++ 安全性的发展趋向进行了详细阐释。&lt;/p&gt;

&lt;p&gt;Stroustrup 称当前是“一个机会”，他强调，类型和资源安全从 C++ 诞生之初就一直是它的目标。“我们当时的硬件无法提供完全的安全性，现在也无法对所有语言和所有用例提供完全的安全性。”但是 Stroustrup 也不希望看到对 C++ 表达的限制，事实上他设想了一个仍然遵循该语言的 ISO 标准的解决方案。&lt;/p&gt;

&lt;p&gt;“我们需要它是 C++。也就是说，我们能做什么不应该受到限制，即使我们如何做可能会受到限制。”&lt;/p&gt;

&lt;p&gt;与此同时，Stroustrup 也不希望看到大量的额外运行时开销。“性能不应该有任何下降......实际上，编写安全代码的一些技术可以提高性能。我主要谈论的是编译器和静态检查可以做什么，因为它是免费的，或者实际上可以提高性能。”&lt;/p&gt;

&lt;p&gt;Stroustrup 找到了他的解决方案：配置文件。也就是说，一套规则，只要遵守，就能实现特定的安全保证。它们将由 ISO C++ 标准定义，解决常见的安全问题，如指针和数组范围。&lt;/p&gt;

&lt;p&gt;至于添加新工具的困难，Stroustrup 指出，C++ 编译器本身现在是一个相当复杂的静态分析器，也可以满足配置文件的要求。因此，在添加提高安全性的工具时，“我认为配置文件注释应该有助于解决这个问题”。&lt;/p&gt;

&lt;p&gt;Stroustrup 列出了一般策略：使用静态分析来消除潜在的错误。但 Stroustrup 补充说：“全局静态分析是负担不起的。”&lt;/p&gt;

&lt;p&gt;“所以基本上我们需要规则来简化我们正在编写的内容，使其能够高效、低成本地分析——本地静态分析……然后提供库，使依赖这些规则变得可行。”&lt;/p&gt;

&lt;p&gt;另外，他还指出了这种策略的另一个优势：“支持从旧代码到提供担保的现代代码的逐步转换。”将有一套标准的“基本”担保，以及更大、更开放的可用担保。Stroustrup 说:“我想象的是类型和资源安全，内存安全，范围安全。诸如算术安全之类的东西是可以标准化的。”此外，还将制定规则，对不同的代码片段应用不同的保证。代码甚至可以得到应用了哪些保证的显式表达式 (从而使将来的读者放心)。&lt;/p&gt;

&lt;p&gt;Stroustrup 简要说明了一点：“小心”是行不通的。因此，虽然核心指导方针可能建议安全的编码实践，但“我们需要强制执行的规则”。&lt;/p&gt;

&lt;p&gt;“我们必须制定安全使用的规则。我们必须提供方法来验证人们是否真的在做他们想做的事情。”Stroustrup 指出，他所描述的大部分内容已经被尝试过，甚至有规模化的实践。“但这些都没有被整合成一个一致的、连贯的整体。这就是我认为我们应该做的。”&lt;/p&gt;

&lt;p&gt;“卫生规则 + 静态分析 + 运行时检查”就是被提炼出的公式。Stroustrup 说 C++ 可以消除许多常见的错误，包括未初始化的变量，范围错误，空指针解引用，资源泄漏和悬空引用。&lt;/p&gt;

&lt;p&gt;在演讲接近尾声时，Stroustrup 谈到了更多的细节。“我建议你采用基于模块的控件。”&lt;/p&gt;

&lt;p&gt;还在开发中的是代码内控件，用于代码片段。&lt;/p&gt;

&lt;p&gt;目前这项工作还在进行中，你可以查到与之相关的论文和讨论。Stroustrup 谈到：“从经典的 C，从‘带类的 C’，到 C++11，我们已经走了很长很长的路。”&lt;/p&gt;

&lt;p&gt;面向开发者，Stroustrup 建议用户可以帮助完善配置文件并将其规范形式化。“我梦想着像 Profiles Light 这样的东西，它提供了配置文件的大部分保证，但不能做所有最后的事情，因为，比如说，静态分析器还不能做到这一点。”&lt;/p&gt;

&lt;p&gt;Stroustrup 创建了一个 GitHub 存储库，“人们可以在那里提出建议，我将把我的草稿等放在那里，这样我们就可以创建一个社区，致力于在合理的时间内完成这些事情。&lt;/p&gt;

&lt;p&gt;存储库询问需要什么才能使配置文件成为“满足各种 C++ 安全需求的全行业工具”，并将该概念称为框架。“为了实现广泛使用，必须创建和安装许多部件。虽然我们已经做了很多工作，但广泛可用的相对较少。这是一个愿望清单。请尽你所能提供帮助。”&lt;/p&gt;

&lt;p&gt;参考链接：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thenewstack.io/bjarne-stroustrups-plan-for-bringing-safety-to-c/" rel="nofollow" target="_blank"&gt;https://thenewstack.io/bjarne-stroustrups-plan-for-bringing-safety-to-c/&lt;/a&gt;
&lt;span class="embed-responsive embed-responsive-16by9"&gt;&lt;iframe class="embed-responsive-item" src="//www.youtube.com/embed/I8UvQKvOSSw" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Thu, 02 Nov 2023 18:27:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/43443</link>
      <guid>https://ruby-china.org/topics/43443</guid>
    </item>
    <item>
      <title>前端根本不需要构建！“技术邪教”Ruby on Rails 之父再出激进言论！</title>
      <description>&lt;p&gt;在近日的 Rails World 大会上，Ruby on Rails 之父、37signals 联合创始人兼首席技术官 DHH（David Heinemeier Hansson）发表了观点称，最快的打包工具就是没有构建 (No Build)，有了 HTTP/2 以及浏览器原生支持 ES Modules，前端根本不需要构建。&lt;/p&gt;
&lt;h2 id="“复杂性已经堆叠得太高了”"&gt;“复杂性已经堆叠得太高了”&lt;/h2&gt;
&lt;p&gt;“我们正在构建一切，一切的一切。”DHH 说道。目前，市面上正不断涌现种种令人兴奋的新框架和新库。“新生的事物太多了，可能我们必须得依靠 AI 提供的建议才能想明白该怎么应对。”&lt;/p&gt;

&lt;p&gt;DHH 认为，人们似乎获得了越来越多能够创建出略好一点新版本的工具，但投入却一路飙升。这不是正确的方向、也不是理想的发展状态。&lt;/p&gt;

&lt;p&gt;DHH 以自己当时开发 Ruby on Rails 的经历为例称，团队最初的立项是 BaseCamp 框架，前后花了约六个月时间，成员只有一位开发者加两名兼职设计师。最终 BaseCamp 建立起出色的业务，多年间创造了数亿美元的收入。“既然我们在 2003、2004 年那会儿就能做到，那么 2023 年我们理应做得更多。”&lt;/p&gt;

&lt;p&gt;对于企业需要用很长的时间才能做出一点改进的原因，DHH 认为其中重要一点是，在生产力低下的时代，取得早期成功的那些企业定下了标准，其他人即使意识到自己需要一点不同的东西，也很难做出实质性的变革：要么效果没有大厂同类方案好，要么就是不具备同样的可扩展性。&lt;/p&gt;

&lt;p&gt;“根据一位 Twitter 前员工的说法，他们决定脱离 Rails 是因为之前的架构设计不好，于是他们决定转向当时认为更好的 Java 微服务这边。但很长一段时间过去，工作并没有什么进展。他们完成了立项，又雇用了好几千人，但毫无进展。Twitter 的例子基本就是生产力黑暗时代的常态，人们认为工作在推进，但增量收益却极其有限。顺带一提，Airbnb 那边也有类似的情况，这已经成了一种趋势。JavaScript 框架造成的类似问题还有很多，甚至开始拖累整个行业的发展速度。”DHH 以 Twitter 为例论述道。&lt;/p&gt;

&lt;p&gt;DHH 还提到，过去 10 年到 15 年间，技术栈分化问题也给开发人员带来了困扰。架构师想要解决的只是他们认为能解决的问题，但未必是真正重要的问题。所以大家需要关注的是能做到哪些以往做不到的事，而每个人都应该努力成为全栈开发者。&lt;/p&gt;

&lt;p&gt;总而言之，DHH 认为，过去 10 到 15 年间复杂性已经堆叠得太高了，现在是时候把简单性作为新的目标了。&lt;/p&gt;
&lt;h2 id="如何实现“无构建”"&gt;如何实现“无构建”&lt;/h2&gt;
&lt;p&gt;就前端领域而言，某种程度上讲，它已经走进了一种“死循环”——虽然它也获得了一定实质性的进展，改变了如今开发 Web 应用程序的基本预期，但紧跟潮流正变得越来越困难。&lt;/p&gt;

&lt;p&gt;对于前端的简化，DHH 提出了“没有构建”的理念。“只要存在构建，那就只能提速。如果根本没有构建，那速度不就到头了？”&lt;/p&gt;

&lt;p&gt;“最先进的（打包）技术不再是寻找更复杂的方法来构建 JavaScript 或 CSS，因为前端根本不需要构建。现在可以依靠 HTTP/2 和对 import map 的普遍支持来避免打包。”DHH 介绍称。&lt;/p&gt;

&lt;p&gt;import map 直译过来是“导入映射”，可以让开发者直接在页面上管理模块，而不需要通过打包构建。“import map 堪称是 Rail 7 中的一次大冒险。”DHH 表示，配合 HTTP2 一道，import map 就构成了一条加载瀑布流，通过一系列独立的脚本让所有的内容都能同时加载，而不必再将 JS 拆分成一个个包。开发者可以更轻松、更顺畅地使用 esBuild，甚至不再需 Bun 的协助。&lt;/p&gt;

&lt;p&gt;“No Build”还具备其他一些奇妙的功能，例如用户可以在任何网站上直接查看源，其内容不涉及任何源映射、不需要任何捆绑，它们就是开发出所编写的文件，未必是编译的纯 JS 文件。一切都能直接交付、不需要经过构建，直接在浏览器端呈现。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://static001.geekbang.org/infoq/30/30669e207aab612a6a6f7daa921fc934.png" title="" alt="alt 文本"&gt;&lt;/p&gt;

&lt;p&gt;对于 Gamil 那种极为复杂且充满交互的产品，DHH 认为，HAML 可以解决。“HAML 为此而生，我们可以借此编写出纯 JS 代码而且无需任何构建。这让我非常兴奋，也是我们目前的主要开发方式。”&lt;/p&gt;

&lt;p&gt;没有构建的理念正在迅速普及，如今也已经进入了 CSS，并推出了大受欢迎的 CSS 嵌套功能。现在所有浏览器都支持 CSS 编译，所有浏览器都支持自定义属性即变量。&lt;/p&gt;

&lt;p&gt;DHH 透露，现在 37 Signals 的新应用开发中也在运用这两大功能：无需构建 JS 代码和无需构建 CSS。“之前我们就考虑过使用嵌套和变量来回避构建。事实证明没有构建不仅是可能的，而且具有极其重大的意义，我们耗费了约十年时间才破解这种复杂性。”&lt;/p&gt;

&lt;p&gt;DHH 表示，绝大多数静态站点不需要花哨的构建管道。Server Side Includes（SSI）被严重低估了。他提出可以将一个 Jekyll 站点转换为 SSI。“一旦将静态站点转换为 SSI，我就会将这些简化为一个新工具，让它们变得简单。拥有一种巧妙的石器时代技术，可在 5 秒内自动推送更新。只需为其提供一个小型虚拟机即可，每月花费应该不会超过 5 美元。”&lt;/p&gt;

&lt;p&gt;DHH 还表示，这一年半以来，37 Signals 开始转向 propshaft，这个新库用于在 Rails 侧无需编译的前提下提供资产管道。它的基本功能只有两个：为所有资产提供加载路径，以便在任意视图中访问任意位置上的 gem 及其他资产；提供摘要标记，从而确保拥有良好的远期动态缓存。&lt;/p&gt;

&lt;p&gt;在推特上，DHH 还展示了公司主站的性能表现，他表示 HEY 主要应用运行的 JavaScript 代码没有经过构建。“我认为我们在 No Build、import map 和大约 100 个单独的 JS 文件方面做得很好！我们发送 500kb 的未压缩 JS，而 Gmail 则发送 10mb！”&lt;/p&gt;

&lt;p&gt;&lt;img src="https://static001.geekbang.org/infoq/8d/8d6dcc64b081f30af79cbf3c7ec6e18e.jpeg" title="" alt="alt 文本"&gt;&lt;/p&gt;

&lt;p&gt;“在 es6 以及 JS 世界中一系列基础进展的支持下，如今的前端代码已经做好了跨越复杂性之桥的准备。我知道，现在的方案仍然有点复杂，但从结果上看所有付出都绝对物有所值。”DHH 表示，“我们目前最应该做的是：在现代 Web 应用程序的构建过程中，剔除一切形式的 JS 捆绑或转译。当然，这样的未来是等不来的，我们应该从现在开始转换自己的开发思路。”&lt;/p&gt;
&lt;h2 id="真有用还是噱头而已？"&gt;真有用还是噱头而已？&lt;/h2&gt;
&lt;p&gt;对于 DHH 提出的“No Build”理念，Vercel CTO Malte Ubl 在推特上表示，他们已尝试过，但结果是行不通。因为在 HTTP2 中，每个请求的开销仍然非常大，并且存在并发限制，此外还会出现瀑布流和低效压缩。目前，“打包”对于高性能网站来说是无法绕过的。&lt;/p&gt;

&lt;p&gt;DHH 不认可 Malte Ubl 所说的“行不通”。他表示，这就是技术讨论的奇怪之处。即便已经有案例证明项目能完成大规模任务（如 Rails 之于 Shopify），但人们也会声称它不能进行扩展。或者已顺利使用某种方法多年（如 no build JS 之于 HEY 网站），也会有人说这套“行不通”。&lt;/p&gt;

&lt;p&gt;还有人觉得这个只是噱头。推特网友“Viking”表示，自从移除 TypeScript 后，DHH 越来越激进了。甚至有网友称 DHH 散发出令人不安的“邪教领袖”气息。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://static001.geekbang.org/infoq/de/de06751edb1d2858eff5f97a75743f82.png" title="" alt="alt 文本"&gt;&lt;/p&gt;

&lt;p&gt;开发者 Nander 表示，“构建时间并不重要，重要的是 FCP（First Contentful Paint，从开始加载到页面内容的任意部分在屏幕上渲染出来的时间）。导入映射时间并不比位于同一服务器上的 RSC（构建步骤）和最小化捆绑包（构建步骤）快。”&lt;/p&gt;

&lt;p&gt;“Chrome 删除了 HTTP/2 的多路复用，它并不比捆绑更有效率。HTTP/3 已经解决了这个问题，并且可能证明捆绑已经成为过去。但据我所知，还没有人尝试过 HTTP/3 多路复用 esm 服务器。Node、Deno 和 Bun 甚至还没有支持 HTTP/3。”Joe Pea 说道。&lt;/p&gt;

&lt;p&gt;还有开发者指出，不打包=把开发细节暴露给用户，浏览器原生支持不等于高效。build 是快了，但运行时慢了的话还划算吗？前端工程化的一个重要里程碑就是引入了 build 步骤，让开发体验和用户体验分离，特别是几百个不同版本的、不同浏览器的用户体验完全分离，这才让开发者真正解放了。&lt;/p&gt;

&lt;p&gt;有开发者很喜欢这个主意。Rails 开发者 Niklas Häusele 表示，“我喜欢用‘No Build’的方式进行本地开发。无需等待即可刷新，这就是最高的生产力。我甚至删除了 &lt;code&gt;tailwindcss-rails&lt;/code&gt; 并将其替换为 tailwind CDN，以避免必须在本地运行任何内容。对于 tailwindcss-rails gem 来说，这将是一个有趣的默认值。”&lt;/p&gt;

&lt;p&gt;对于 DHH“没有构建”的理念，你有什么看法？欢迎在评论区留下你的想法。&lt;/p&gt;

&lt;p&gt;参考链接：
&lt;span class="embed-responsive embed-responsive-16by9"&gt;&lt;iframe class="embed-responsive-item" src="//www.youtube.com/embed/iqXjGiQ_D-A" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/dhh/status/1713615147393323408" rel="nofollow" target="_blank"&gt;https://twitter.com/dhh/status/1713615147393323408&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/cramforce/status/1712265070213050390" rel="nofollow" target="_blank"&gt;https://twitter.com/cramforce/status/1712265070213050390&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/cramforce/status/1712265070213050390" rel="nofollow" target="_blank"&gt;https://twitter.com/cramforce/status/1712265070213050390&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://world.hey.com/dhh/you-can-t-get-faster-than-no-build-7a44131c" rel="nofollow" target="_blank"&gt;https://world.hey.com/dhh/you-can-t-get-faster-than-no-build-7a44131c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;本文转载来源：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.infoq.cn/article/9k37mArAJlY708eGOkVP" rel="nofollow" target="_blank"&gt;https://www.infoq.cn/article/9k37mArAJlY708eGOkVP&lt;/a&gt;&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Fri, 20 Oct 2023 11:52:43 +0800</pubDate>
      <link>https://ruby-china.org/topics/43407</link>
      <guid>https://ruby-china.org/topics/43407</guid>
    </item>
    <item>
      <title>上云一年烧掉 320 万美元，Ruby on Rails 之父：“下云”成功，五年能省 700 万美元！</title>
      <description>&lt;p&gt;高达 320 万美元一年的云计算费用，这家公司选择“下云”后，CTO 粗略算了一下，每年至少能节省一百五十万美元。即使预留 50 万美元用于意外开支，5 年也能节省 700 万美元的费用。&lt;/p&gt;

&lt;p&gt;整理 | 梦依丹 出品 | CSDN（ID：CSDNnews）
近日，37Signals 联合创始人&amp;amp;CTO David Heinemeier Hansson (下文简称 David，其还是 Ruby on Rails 框架创始人) 兴奋地表示：本以为“下云”会像进入云端那样，需要花费多年时间，没想到在经历六个月的努力后，最后一个应用已成功迁回到本地硬件之上。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/nuanshuidai/7e79c128-a227-456d-803d-1ea06456cddc.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;对此，也有不少人咨询 David 是如何做到的？有人直言，除了钱之外，在发生自然灾害时，如何保证可用性？并且是否意味着数据中心需要遍布世界各地，或者依然在云上维护关键备份。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/nuanshuidai/324d4c9f-29f8-4881-83a4-c352a846ee65.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="为什么要“下云”"&gt;为什么要“下云”&lt;/h3&gt;
&lt;p&gt;2022 年 10 月 19 日，David 宣布 37Signals 旗下两个主要产品 Basecamp 和 HEY 正式“下云”。Basecamp 是非常火的一款 Web 端项目管理和团队协作平台，用户群来自五大洲 166 个国家的大大小小的企业，超 75,000 个组织在使用，已在云上运行十多年。而全功能电子邮件服务 HEY 自 3 年前推出，就一直跑在云端。&lt;/p&gt;

&lt;p&gt;在决定“下云”之前，他们广泛地使用了 Amazon 和 Google 的云服务，并且在裸机虚拟机，Kubernetes 容器上做过尝试，也体验了云计算所提供的一些服务。但在诸多尝试之后，他们得出结论，对于像他们这样具有稳定增长的中型企业来说，租用计算机在大多数情况下是一个不划算的选择。运营商所承诺的通过降低复杂性，减少运营支出之类的费用节省也从未实现。&lt;/p&gt;

&lt;p&gt;37Signals 已经经营了 20 多年，这是一家中型企业，拥有约 80 多名员工和 10 人左右的运营团队，以及超过十万的客户。很多情况下，他们都会有一个可预测的基础负载，并不会有剧烈的波动。与此同时，公司内部在运行服务器方面具备相当多的能力和经验。他们用户量最大的应用程序 Basecamp 只有搜索 (OpenSearch)、文件存储 (S3) 和 CDN 服务 (CloudFront) 是放在云端，其它绝大部分包括 Basecamp 2 几乎完全跑在自己的服务器上，包括应用程序、数据库和缓存服务器。&lt;/p&gt;

&lt;p&gt;因此，团队成员对本地部署和云上都比较熟悉，能够客观地看待在哪些场景下，使用何种部署。所以他们才着手制定了离开计划。&lt;/p&gt;
&lt;h4 id="6 个月迁移成功"&gt;6 个月迁移成功&lt;/h4&gt;
&lt;p&gt;本次迁移最大的挑战是 HEY 应用程序，这是完全基于云端并从未在自己硬件上运行过的全功能电子邮件服务。HEY 使用的 AWS 云服务包括通过 EKS 在 Kubernetes 集群上运行完整的 Rails 应用程序、使用 Aurora RDS 在 MySQL 数据库服务器上运行、通过 Elasticache 在 Redis 上运行以及通过 OpenSearch 进行搜索。此外，还有一些其它的旧版应用程序也在 EKS 上运行，并使用 RDS 作为数据库。&lt;/p&gt;

&lt;p&gt;为此，团队采用分阶段迁移法，在几周内独立地移动不同数据库、缓存服务器、邮件服务和应用实例，最终成功地完成了此次迁移。&lt;/p&gt;

&lt;p&gt;在过去的六个月中，他们还将六项遗产服务带回了本地。这些服务已不再对外销售，但只对现有客户和用户提供支持，直至互联网终结的六项产品，它们分别是：Basecamp Classic、Highrise、Writeboard、Campfire、Backpack 和 Ta-da 列表都已经超过十年历史了，但仍然为数以万计的人提供服务，并创造了数百万美元的收入。&lt;/p&gt;

&lt;p&gt;接下来，Basecamp 团队将花费更少的资金来运营它们。因为设备的更新换代，还给客户带来更快更好的用户体验。&lt;/p&gt;

&lt;p&gt;后边，David 团队成员会使用一些开源技术堆栈来管理这些应用程序：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;KVM 将新型 192 线程 Dell R7625s 切片成隔离虚拟机；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker 运行容器化应用程序；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MRSK 使用 Manage Remote Server Kontainers 进行零停机时间应用部署和回滚操作，这些设置避免了 Kubernetes 的复杂性，并避免了企业服务上的合同纠葛。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在整个迁移过程中，运营团队规模并没发生改变，在云端运行的应用程序并没有提供承诺中所述的生产力增益来缩小团队规模。&lt;/p&gt;

&lt;p&gt;主要区别在于需要新服务器和看到它们在线上之间存在的延迟时间。虽然在云端可以几分钟就启动 100 台强大的计算机，但也必须付出高昂的成本来享受此特权。而他们并没有哪些业务需要享受这种云上高级服务，因此他们所节省下来的费用完全可以承受极度超额配置的服务器需求，即使需要更多的时候，也只需要几周即可搞定。&lt;/p&gt;

&lt;p&gt;DHH 列举了他们采购硬件的花费及相关配置：花费约 50 万美元从 Dell 购买了两批服务器，并将其组合为 4,000 个虚拟 CPU、7,680 GB 的 RAM 和 384TB 的 NVMe 存储容量。&lt;/p&gt;

&lt;p&gt;上面的服务器配置完全可以运行他们的遗产服务和 HEY 应用程序，并刷新其他 Basecamp 操作所需的硬件。而且，这还不到每年节省成本的三分之一，还是他们在五年内所摊销的硬件。&lt;/p&gt;
&lt;h3 id="年费高达 320 万美元的云成本"&gt;年费高达 320 万美元的云成本&lt;/h3&gt;
&lt;p&gt;在 David 宣布“下云”操作后，不少公司来咨询 David 当前的账单情况以及节省的成本是否可以支撑“下云”这个决定。&lt;/p&gt;

&lt;p&gt;为此，David 在博客上公布了他们在云上的具体支出。&lt;/p&gt;

&lt;p&gt;2022 年，他们在所有云服务上总共花费了 3,201,564 美元。相当于每月 266,797 美元。&lt;/p&gt;

&lt;p&gt;对于 HEY 应用来说，生产工作负载的年度费用为 1,066,150 美元（88,846 美元/月）。该服务分为以下几个大部分：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/nuanshuidai/f87b9070-357d-4d26-8e9d-7a1b4f614c6b.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;就单服务而言，他们在 2022 年为所有应用程序数据库的 RDS 花费了 473,196 美元（每月 39,433 美元）。这些费用里面不包括 Basecamp 和 Basecamp 2。因此，其中大部分是花在 HEY 应用上的，该服务占据了全年总额的 355,950 美元（或每月 29,662 美元），其余则用于其他旧版服务。&lt;/p&gt;

&lt;p&gt;用来托管应用程序搜索集群和索引存储日志管道的 OpenSearch，在 2022 年花费了 519,959 美元（每月 43,330 美元）。这是 Basecamp 和 Basecamp 2 使用的云服务之一，大笔开支分别分布在 HEY 和 Basecamp Classic 上。&lt;/p&gt;

&lt;p&gt;2022 年在亚马逊 Kubernetes 服务 EC2 和 EKS 总共花费了 759,983 美元（每月 63,331 美元）。其中绝大部分用于 HEY 的生产和暂存环境，总计 272,359 美元（每月 22,696 美元），其余用于其他遗留应用程序。值得注意的是，这些支出都与当前的 Basecamp 或 Basecamp 2 无关。&lt;/p&gt;

&lt;p&gt;对于 Elasticache 部分，2022 年花费了 123,852 美元（每月 10,321 美元）。其中最大部分再次由 HEY 所占据，通过使用该服务来获取基于 Redis 的缓存。&lt;/p&gt;

&lt;p&gt;最后，在 S3 存储的 8 PB 文件上花费了 907,838 美元（每月 75,653 美元）的费用。值得一提的是，这个设置采用了双区域复制策略，目的是可以抵御整个 AWS 区域消失的风险，包括所有可用区。为了服务这些文件和其他静态资源，他们在 2022 年还花费了 66,742 美元（每月 5,562 美元）购买 CloudFront CDN 服务。&lt;/p&gt;

&lt;p&gt;这就是他们 2022 年在云上所花费的巨额支出。David 表示，等到一年结束时，他还会继续对比云上和建立本地物理数据中心的费用对比，从而看看“下云”方案所节省下的成本。&lt;/p&gt;
&lt;h3 id="那么，“云”还能上吗？"&gt;那么，“云”还能上吗？&lt;/h3&gt;
&lt;p&gt;David 还表示，云计算只在两种情况下会比较出色，一是当您的应用程序非常简单且流量较低时，通过使用完全托管的服务确实可以降低复杂性。Heroku 就是这样起步的，并且 Render 等公司验证了可行性。当你还没有客户时，或者开始有一些客户时，云服务托管可以算是一个绝佳的选择。&lt;/p&gt;

&lt;p&gt;第二种情况是当负载非常不规则或者较大时。当您的使用量出现剧烈波动或高峰时，基线只占最大需求的一小部分，或者您不知道需要十台服务器还是一百台服务器时。在这种情况下，没有什么比上云更好的选择了。提到这里，David 以 HEY 为例，团队起初计划是 6 个月内有 3 万名用户，而实际却在 3 周内涌进了 30 万名体验用户。HEY 从一出生就运行在云端，所以才避免了流量剧烈波动所带来的的不良体验。&lt;/p&gt;

&lt;p&gt;David 认为，云对于那些处于生命周期早期、支出微不足道或者存在 24 个月内可能无法继续经营的公司来说是有用的。但要当心，不要把那些慷慨的云服务赠品看成礼物，这是一个陷阱。如果你过多地依赖他们专有的托管服务或无服务器方案，一旦账单开始飙升，你会发现很难逃脱。&lt;/p&gt;

&lt;p&gt;对于一个企业来说，每笔费用的支出都很重要。David 提醒大家：“可以考虑一下你是否拥有一个真正受益于不断扩大和缩小容量的服务，然后认真评估自己的云计算退出可能会是什么样子。我们在六个月内从云上取出了七个应用程序，你也可以做到这一点。工具都在那里，而且是免费的。所以不要只因为炒作而留在云端。”&lt;/p&gt;

&lt;p&gt;参考链接：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://basecamp.com/" rel="nofollow" target="_blank"&gt;https://basecamp.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://world.hey.com/dhh/we-have-left-the-cloud-251760fb" rel="nofollow" target="_blank"&gt;https://world.hey.com/dhh/we-have-left-the-cloud-251760fb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://37signals.com/podcast/leaving-the-cloud/" rel="nofollow" target="_blank"&gt;https://37signals.com/podcast/leaving-the-cloud/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.37signals.com/our-cloud-spend-in-2022/" rel="nofollow" target="_blank"&gt;https://dev.37signals.com/our-cloud-spend-in-2022/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;转自 CSDN&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Wed, 28 Jun 2023 08:34:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/43200</link>
      <guid>https://ruby-china.org/topics/43200</guid>
    </item>
    <item>
      <title>这网站的链接有问题了。</title>
      <description>&lt;p&gt;我点击右侧的《Ruby or Rails 教程》时，弹出来的网站如下：
&lt;img src="https://l.ruby-china.com/photo/nuanshuidai/f95a5af9-df92-4f6f-a731-18c491ab97c3.png!large" title="" alt=""&gt;
管理员是不是处理下。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Mon, 05 Jun 2023 09:16:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/43141</link>
      <guid>https://ruby-china.org/topics/43141</guid>
    </item>
    <item>
      <title>有没有在 windows 上部署的？</title>
      <description>&lt;p&gt;有没有在 Windows 系统上部署经验的朋友？谈谈经验，谢谢了。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Thu, 16 Mar 2023 10:47:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/42943</link>
      <guid>https://ruby-china.org/topics/42943</guid>
    </item>
    <item>
      <title>WSL2 中和 Linux 子系统双向同步的问题好像已经解决了！</title>
      <description>&lt;p&gt;之前使用 WSL2 时，发现和子 Linux 存在双向同步问题。还发过一篇请教帖，详细的参见：&lt;a href="https://ruby-china.org/topics/40764" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/40764&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;当时纵然可以使用将项目文件存储在子 Linux 系统内解决，但是还是用着不够灵活。虽然这种方式我一直在使用；&lt;/p&gt;

&lt;p&gt;今天突然想起 windows 10 已经更新了好几次，不知这个 BUG 有没有解决。于是就动手测试了下，发现已经可以同步更新了，不用重启 rails server;&lt;/p&gt;

&lt;p&gt;具体的是步骤：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;在 WSL2 下进入/mnt/c 目录下，新建一个 Rails 项目&lt;/li&gt;
&lt;li&gt;用 vs code 打开刚新建的项目，这里不用启动 Remote 模式，就用本地打开方式；&lt;/li&gt;
&lt;li&gt;随便编辑下文档，保存，测试，发现都能正常运行，不用再像以前再重启 Rails server 了；&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这个修复无疑让 WSL2 在开发时更方便灵活了！&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Thu, 13 Jan 2022 14:14:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/42076</link>
      <guid>https://ruby-china.org/topics/42076</guid>
    </item>
    <item>
      <title>部署出错，着急，请教！</title>
      <description>&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/nuanshuidai/181c7a1b-3e66-49d1-8d61-a35d7affa2ca.png!large" title="" alt=""&gt;
上传到云主机后（Centos 7），执行"rake assets:precompile RAILS_ENV=production"时报错，说没权限，如图上所说。
可是我这个目录用过 chmod 777 的权限了，有读写权限。卡在这了，懂的同学请赐教下！&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Sat, 06 Feb 2021 00:16:54 +0800</pubDate>
      <link>https://ruby-china.org/topics/40894</link>
      <guid>https://ruby-china.org/topics/40894</guid>
    </item>
    <item>
      <title>在 WSL 下写 rails 6 项目，必须重启服务器才能刷新页面是什么原因？</title>
      <description>&lt;p&gt;试着在 win10 下安装好了 WSL 环境，用 Vs code 弄了个 Rails 6.1 试例项目，发现修改页面后，必须重启服务器才能刷新修改后的结果。检查开发环境下的配置，config.cache_classes = false 是开启的，WSL 安装的环境是 Ubuntu 20.04 分支。
有在 WSL 下搞项目的同学知道什么原因吗？感谢！&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Wed, 30 Dec 2020 13:40:35 +0800</pubDate>
      <link>https://ruby-china.org/topics/40764</link>
      <guid>https://ruby-china.org/topics/40764</guid>
    </item>
    <item>
      <title> 想单纯的试试 vuejs-rails，为啥引用 vuejs-rails 就是不成功？</title>
      <description>&lt;h2 id="就是想单纯的用一下vuejs-rails这个gem，看看好用不。但就是不成功，情况如下："&gt;就是想单纯的用一下 vuejs-rails 这个 gem，看看好用不。但就是不成功，情况如下：&lt;/h2&gt;
&lt;p&gt;一、先说我做了的：&lt;/p&gt;

&lt;p&gt;1、在 gem 文件里加了：gem 'vuejs-rails'&lt;/p&gt;

&lt;p&gt;2、修改 app/assets/javascripts/application.js，追加内容
      //= require vue&lt;/p&gt;

&lt;p&gt;3、禁用 TurboLinks
      删除 app/assets/javascripts/application.js 中如下内容：&lt;/p&gt;

&lt;p&gt;//= require turbolinks&lt;/p&gt;

&lt;p&gt;修改文件 app/views/layouts/application.html.erb&lt;/p&gt;

&lt;p&gt;删除函数 stylesheet_link_tag 的参数'data-turbolinks-track': 'reload'&lt;/p&gt;

&lt;p&gt;删除函数 javascript_include_tag 的参数'data-turbolinks-track': 'reload'&lt;/p&gt;
&lt;h3 id="二、在已有的erb文件里写了个测试代码，但不成功，代码如下："&gt;二、在已有的 erb 文件里写了个测试代码，但不成功，代码如下：&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div id="app"&amp;gt;
      {{ message_1 }}
&amp;lt;/div&amp;gt; 

&amp;lt;script&amp;gt;
    var app = new vue({
    el: '#app',
    data: {
         message_1: 'Hello Dj!'     
    },
    })
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但页面输出依然是：{{ message_1 }}&lt;/p&gt;
&lt;h3 id="三、问题："&gt;三、问题：&lt;/h3&gt;
&lt;p&gt;这样看来，vuejs-rails 是没用对，但查了好多资料，不都是这种用法吗？请教大家，应该如何正确使用？&lt;/p&gt;
&lt;h3 id="四、还有，如果用最直接的在erb文件里引用vue.js，也无效，就是下面这种用法："&gt;四、还有，如果用最直接的在 erb 文件里引用 vue.js，也无效，就是下面这种用法：&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&amp;gt;&amp;lt;/script&amp;gt;
.......
&amp;lt;div id="app"&amp;gt;
      {{ message_1 }}
 &amp;lt;/div&amp;gt;
 .......
 &amp;lt;script&amp;gt;
    var app = new vue({
    el: '#app',
    data: {
         message_1: 'Hello Dj!'     
    },
    })
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样用也无效，请教大家问题在哪？&lt;/p&gt;

&lt;p&gt;以上用法就是不想用 webpacker 方式，想试试最单纯的用法。不要喷。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Sat, 17 Oct 2020 17:27:36 +0800</pubDate>
      <link>https://ruby-china.org/topics/40486</link>
      <guid>https://ruby-china.org/topics/40486</guid>
    </item>
    <item>
      <title>想了解 Java 微服务横行的当下，还有多少人用 Rails 的？</title>
      <description>&lt;p&gt;当下 Spring cloud 的微服务架构很流行，还有多少人坚持用 Rails 的？很多项目都陆续采用 JAVA 微服务架构来做了，感觉 Rails 群体越来越小了。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Mon, 16 Mar 2020 14:57:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/39616</link>
      <guid>https://ruby-china.org/topics/39616</guid>
    </item>
    <item>
      <title>在 Rails 里如何使用 vue?</title>
      <description>&lt;p&gt;没用过 vue，想请教下 Rails 里如何使用 vue？
vue 和 Rails 的配合程度怎么样呢？&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Sun, 15 Mar 2020 21:52:08 +0800</pubDate>
      <link>https://ruby-china.org/topics/39590</link>
      <guid>https://ruby-china.org/topics/39590</guid>
    </item>
    <item>
      <title>想做个调查，兰州有多少 ruby/rails 同学？</title>
      <description>&lt;p&gt;兰州作为一个落后的城市，有多少学习和使用 ruby/rails 的同学？有的话踩个脚印吧。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Mon, 06 May 2019 06:44:54 +0800</pubDate>
      <link>https://ruby-china.org/topics/38480</link>
      <guid>https://ruby-china.org/topics/38480</guid>
    </item>
    <item>
      <title>做个小小的调查，有多少用 Rails 做服务器后端 API 的？</title>
      <description>&lt;p&gt;现在多转到移动开发方面了，后台服务端有多少用 Rails 开发的？
就 Rails 的效率而言，选择其开发 API 明智吗？
有多少同学这么做的，举个手看看。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Sun, 18 Nov 2018 22:14:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/37788</link>
      <guid>https://ruby-china.org/topics/37788</guid>
    </item>
    <item>
      <title>CarrierWave 上传的问题！</title>
      <description>&lt;p&gt;利用 CarrierWave 上传一些图片，需要同时多张上传。这些图片和表字段无关，就单纯的传文件到服务器，看了 CarrierWave 的接口，类似这样：&lt;/p&gt;

&lt;p&gt;controller 里：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mystore&lt;/span&gt;
    &lt;span class="n"&gt;up_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:localfile&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;myfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;MyuploaderUploader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;myfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;store!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;up_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;试着写了个小 DEMO，代码如下：&lt;/p&gt;

&lt;p&gt;view 里：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= form_for @cang_image do |f| %&amp;gt;
&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;label&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;名称&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt; &lt;span class="o"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= f.text_field :cang_image_name, class: 'form-control' %&amp;gt;
&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;label&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;图例&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;
&amp;lt;%= f.file_field :image ,class: 'form-control',multiple: true %&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%#= f.hidden_field :image_cache %&amp;gt;
&amp;lt;%= f.submit yield(:button_text), class: "btn btn-primary" %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;controller 里的方法：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
       &lt;span class="vi"&gt;@image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cang_image_params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;myfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;CangImageUploader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;        
        &lt;span class="n"&gt;myfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;store!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行时报这样的错：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2017/8e51efd7-8767-465a-9c56-f5a5083cf48d.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;有二个问题：
1：不知怎么解决。
2：store!(&lt;a href="/image" class="user-mention" title="@image"&gt;&lt;i&gt;@&lt;/i&gt;image&lt;/a&gt;) 里的参数有啥具体要求不是很清楚。&lt;/p&gt;

&lt;p&gt;有懂的同学指教下！谢谢！&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Sun, 20 Aug 2017 02:44:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/33884</link>
      <guid>https://ruby-china.org/topics/33884</guid>
    </item>
    <item>
      <title>为什么 select 组件的数据在健壮参数里传不过去？</title>
      <description>&lt;p&gt;不论是普通的 html select 组件，还是 select_tag 组件，都传不过去。&lt;/p&gt;

&lt;p&gt;同样 name 的 text、text_area 都能传过去。奇怪了。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Wed, 09 Aug 2017 06:35:39 +0800</pubDate>
      <link>https://ruby-china.org/topics/33774</link>
      <guid>https://ruby-china.org/topics/33774</guid>
    </item>
    <item>
      <title>健壮参数的写法</title>
      <description>&lt;p&gt;健壮参数有没有反选写法？&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Sun, 06 Aug 2017 03:44:50 +0800</pubDate>
      <link>https://ruby-china.org/topics/33743</link>
      <guid>https://ruby-china.org/topics/33743</guid>
    </item>
    <item>
      <title>想听下大家在 Rails 项目开发中，对前端浏览和后台管理的目录是如何设计的，以及前后有重叠部份的设计，比如用户登录。</title>
      <description>&lt;p&gt;关于前台和后台功能不同，如何良好的进行设计和管理各模块目录？
比如登录要用到的 user 模块，后台管理员即要用到来进行全部用户的管理；前台用户登录和注册、浏览也会用到。
商品模块后台管理要用到，前台浏览也会用到。
相关的 controller 和 view 混杂在一起，确实难管理。
以前没有太划分设计，项目越大，越难管理和阅读。想听听大家的好办法。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Tue, 01 Aug 2017 01:00:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/33684</link>
      <guid>https://ruby-china.org/topics/33684</guid>
    </item>
    <item>
      <title>论坛的样式和形式太老了！</title>
      <description>&lt;p&gt;整个网站的论坛形式太老了，跟时代不同步啊！&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Wed, 10 Aug 2016 01:53:21 +0800</pubDate>
      <link>https://ruby-china.org/topics/30784</link>
      <guid>https://ruby-china.org/topics/30784</guid>
    </item>
    <item>
      <title>目前使用 rails 的主流版本是多少？</title>
      <description>&lt;p&gt;统计下大家使用 rails 的版本情况。&lt;/p&gt;

&lt;p&gt;包括大家对 ruby2.0 和 rails4 的使用情况，都来谈谈吧。&lt;/p&gt;</description>
      <author>nuanshuidai</author>
      <pubDate>Tue, 18 Mar 2014 20:36:12 +0800</pubDate>
      <link>https://ruby-china.org/topics/17980</link>
      <guid>https://ruby-china.org/topics/17980</guid>
    </item>
  </channel>
</rss>
