{
  "version": "https://jsonfeed.org/version/1", 
  "title": "Ruby on Rails", 
  "description": "Full stack web application framework.", 
  "home_page_url": "https://www.v2ex.com/go/ror", 
  "feed_url": "https://www.v2ex.com/feed/ror.json", 
  "icon": "https://cdn.v2ex.com/navatar/43ec/517d/81_large.png?m=1579006983", 
  "favicon": "https://cdn.v2ex.com/navatar/43ec/517d/81_normal.png?m=1579006983", 
  "items": [
    {
      "author": {
        "url": "https://www.v2ex.com/member/zpvip", 
        "name": "zpvip", 
        "avatar": "https://cdn.v2ex.com/avatar/1b4e/e40f/25006_large.png?m=1768120260"
      }, 
      "url": "https://www.v2ex.com/t/1184640", 
      "title": "\u4ee5\u540e\u53d1\u8f6f\u4ef6\u5e93\u662f\u4e0d\u662f\u53ea\u7528\u53d1 spec?", 
      "id": "https://www.v2ex.com/t/1184640", 
      "date_published": "2026-01-11T08:31:09+00:00", 
      "content_html": "<p>X \u4e0a\u770b\u5230 \u962e\u4e00\u5cf0 \u53d1\u4e86\u4e00\u4e2a\u597d\u73a9\u7684\u5e93\uff1a</p>\n<p><a href=\"https://x.com/ruanyf/status/2010225187594334692\" rel=\"nofollow\">https://x.com/ruanyf/status/2010225187594334692</a></p>\n<p><a href=\"https://github.com/dbreunig/whenwords\" rel=\"nofollow\">https://github.com/dbreunig/whenwords</a></p>\n<p>\u987a\u624b\u4e00\u4e2a\u5c0f\u65f6\u5c31 Vibe coding \u4e86\u4e00\u4e2a Ruby Implementation</p>\n<p><a href=\"https://github.com/ZPVIP/whenwords\" rel=\"nofollow\">https://github.com/ZPVIP/whenwords</a></p>\n<p>\u611f\u89c9\u4ee5\u540e\u53ef\u4ee5\u7528 spec \u53d1\u5e93\u4e86</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/zpvip", 
        "name": "zpvip", 
        "avatar": "https://cdn.v2ex.com/avatar/1b4e/e40f/25006_large.png?m=1768120260"
      }, 
      "url": "https://www.v2ex.com/t/1184555", 
      "title": "OpenCode + GLM-4.7 \u8fd8\u662f\u5f1f\u5f1f\uff0c Antigravity + Gemini 3 Pro \u8fd8\u662f\u5f3a\u4e0d\u5c11\uff0c\u4e0d\u5199\u4e00\u884c\u4ee3\u7801\u8f6c\u8bd1\u4e86\u4e00\u4e2a Gem: rb-edge-tts", 
      "id": "https://www.v2ex.com/t/1184555", 
      "date_published": "2026-01-10T18:40:14+00:00", 
      "content_html": "<p>\u539f\u5e93\u662f Python \u5199\u7684\uff1a\n<a href=\"https://github.com/rany2/edge-tts\" rel=\"nofollow\">https://github.com/rany2/edge-tts</a></p>\n<p>\u6211\u5148\u7528 OpenCode + GLM-4.7 \u8f6c\u6210 Ruby Gem. \u63d0\u793a\u8bcd\uff1a</p>\n<p>\u8be6\u7ec6\u7814\u8bfb python \u4ee3\u7801\uff0c\u5e2e\u6211\u628a\u8fd9\u4e2a\u529f\u80fd\u5e93\u8f6c\u6362\u6210\u4e00\u4e2a Ruby gem, \u5e76\u5199\u51fa\u76f8\u5e94\u7684 <a href=\"http://README.md\" rel=\"nofollow\">README.md</a>, \u6bd4\u5982 \u5b89\u88c5\uff0c\u8c03\u7528\u7b49\u3002</p>\n<p>\u6700\u540e\u6ca1\u6210\u529f\uff0c\u7136\u540e\u5b83\u5728\u6839\u76ee\u5f55\u7559\u4e0b\u51e0\u4e2a markdown \u6587\u4ef6\u5206\u6790\u4e86\u4e00\u4e0b\u5b83\u89c9\u5f97\u7684\u95ee\u9898\u6240\u5728\uff0c\u7136\u540e\u5c31\u4e0d\u7ba1\u4e86\u3002\u6bcf\u6b21\u8ba9\u5b83\u7ee7\u7eed\u8fd8\u662f\u641e\u4e0d\u5b9a\u3002\u6ca1\u6709\u4e70\u5176\u5b83\u6a21\u578b\uff0c\u8bf4\u4e0d\u5b9a\u5176\u5b83\u6a21\u578b\u6548\u679c\u4f1a\u597d\u4e00\u70b9\u3002</p>\n<p>\u6700\u540e\u8fd8\u662f\u5728 Antigravity + Gemini 3 Pro \u4e0b\u4e1d\u6ed1\u5b8c\u5de5\uff1a\n<a href=\"https://github.com/ZPVIP/rb-edge-tts\" rel=\"nofollow\">https://github.com/ZPVIP/rb-edge-tts</a> (\u6b22\u8fce\u8bd5\u7528\uff0c\u53d1 Issue \uff0cPR)</p>\n<p>\u5168\u7a0b\u6211\u90fd\u6ca1\u6709\u5199\u4ee3\u7801\uff0c\u8fd9\u5728\u4ee5\u524d\u6839\u672c\u65e0\u6cd5\u60f3\u8c61\u3002</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/cj323", 
        "name": "cj323", 
        "avatar": "https://cdn.v2ex.com/gravatar/55d8713a4741083ba73747a518298a1f?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/1099039", 
      "title": "Ruby on Rails \u7528\u7740\u592a\u8212\u670d\u4e86", 
      "id": "https://www.v2ex.com/t/1099039", 
      "date_published": "2024-12-20T05:14:01+00:00", 
      "content_html": "<p>\u5b9e\u5728\u5fcd\u4e0d\u4f4f\u6765\u53d1\u4e00\u8d34\u5439\u4e00\u4e0b Ruby on Rails \u3002\u8fd9\u4e24\u5929\u7528\u4e86\u4e00\u4e0b\uff0c\u7b80\u76f4\u592a\u723d\u4e86\u3002</p>\n<p>\uff08\u5728\u4e0b\u4e4b\u524d\u4e00\u76f4\u662f\u5728\u4e2d\u5c0f\u4f01\u4e1a\u505a\u5168\u6808\uff0c\u7528\u8fc7\u4e00\u4e9b\u5176\u4ed6\u7684\u8bed\u8a00\u548c\u6846\u67b6\uff0c\u4e3b\u8981\u662f\u7528 Node/Python \u540e\u7aef+React/Vue \u524d\u7aef\uff0c\u4e2a\u4eba\u9879\u76ee\u4e5f\u7528\u8fc7 Next/Nuxt \u3002\u7528 Rails \u611f\u89c9\u5f88\u4e0d\u4e00\u6837\uff0c\u8fd9\u91cc\u5206\u4eab\u4e00\u4e0b\u3002\uff09</p>\n<p>\u9996\u5148\uff0cRuby \u8bed\u8a00\u5f88\u5e26\u7f8e\u611f\u3002</p>\n<ol>\n<li>\u6ca1\u6709 type \uff0c\u6211\u4e2a\u4eba\u5f88\u559c\u6b22\uff0c\u811a\u672c\u8bed\u8a00\u5c31\u5e94\u8be5\u8fd9\u6837\uff0c\u81ea\u7531\u4fbf\u6377\u3002\u867d\u7136\u5de5\u7a0b\u5316\u5dee\u4e00\u70b9\uff0c\u4f46\u662f\u5199\u7740\u8212\u670d\u3002</li>\n<li>\u7b80\u6d01\uff0c\u540c\u6837\u7684\u4e1c\u897f\u53ef\u4ee5\u7528\u66f4\u5c11\u7684\u5b57\u7b26\u5b9e\u73b0\uff0c\u540c\u65f6\u53c8\u6bd4\u8f83\u597d\u7406\u89e3\u3002</li>\n</ol>\n<p>\u5176\u6b21\uff0cRails \u662f\u5f88\u5b8c\u5584\u53c8\u7cbe\u7f8e\u7684\u6846\u67b6</p>\n<ol>\n<li>\u81ea\u5e26\u7684\u5de5\u5177\u6781\u5176\u5b8c\u6574\uff0c\u6211\u4e4b\u524d\u63a5\u89e6\u7684\u6846\u67b6\u6700\u5b8c\u6574\u7684\u5e94\u8be5\u5c31\u662f Django \uff0c\u4f46\u662f\u548c Rails \u76f8\u6bd4\u7b80\u76f4\u5c0f\u5deb\u89c1\u5927\u5deb\u3002Rails \u51e0\u4e4e\u4e0d\u9700\u8981\u7b2c\u4e09\u65b9\u4f9d\u8d56\uff0c\u4e5f\u4e0d\u7528\u4e0a\u4e91 - db, orm, caching, storage, REPL, test, i18n, mailer \u7b49\u7b49\u90fd\u662f\u76f4\u63a5\u5f00\u7bb1\u7528\uff1a\u8fd9\u4e9b\u968f\u4fbf\u4e00\u4e2a\u5728 Javascript/Python \u751f\u6001\u91cc\u5f80\u5f80\u90fd\u662f\u8981\u7b2c\u4e09\u65b9\u4f9d\u8d56\u751a\u81f3\u4e91\u670d\u52a1\uff0c\u9ebb\u70e6\u5f88\u591a\u3002</li>\n<li>Model(ApplicationRecord)\u7528\u7740\u5f88\u8212\u670d\uff0c\u5f88\u591a\u5f88\u65b9\u4fbf\u7684\u7ec6\u8282\uff0c\u968f\u4fbf\u4e3e\u4e2a\u4f8b\u5b50\u6bd4\u5982 dirty methods \u7c7b\u4f3c<code>*_previously_changed?</code>\u6216\u8005<code>*_previously_was</code>\uff1b\u8fd9\u79cd\u57fa\u7840\u903b\u8f91\u5728\u5176\u4ed6\u6846\u67b6\u4e0b\u57fa\u672c\u90fd\u8981\u81ea\u5df1\u5b9e\u73b0\uff0crails \u76f4\u63a5\u81ea\u5e26\uff0c\u7701\u4e0d\u5c11\u4e8b\u3002</li>\n</ol>\n<p>\u6700\u540e\uff0cRuby \u751f\u6001\u6211\u5f88\u559c\u6b22\uff0c\u5f53\u7136\u8fd9\u91cc\u6211\u559c\u6b22\u7684\u70b9\u4e0d\u662f\u706b\u7206\u7a0b\u5ea6\u4ee5\u53ca\u5de5\u5177\u591a\uff0cRuby \u5f53\u7136\u8fdc\u6ca1\u6709 Python/Javascript \u70ed\u3002\u4f46\u662f\u6211\u80fd\u63a5\u89e6\u5230\u7684 Ruby \u8bba\u575b\u548c\u5f00\u6e90\u9879\u76ee\u90fd\u662f\u70ed\u5ea6\u6070\u5230\u597d\u5904 - \u4e3b\u8981\u4f53\u73b0\u5728\u4eba\u4e0d\u662f\u592a\u591a\uff0c\u8fed\u4ee3\u65b0\u4e8b\u7269\u901f\u5ea6\u4e0d\u662f\u90a3\u4e48\u6fc0\u8fdb\u3002\u8fd9\u70b9\u5f88\u597d\uff0c\u4e0d\u6298\u817e\u3002\u5bf9\u6bd4 JS \u751f\u6001\uff0c\u540c\u6837\u7684\u95ee\u9898\u603b\u6709\u4e00\u5927\u5806\u7c7b\u4f3c\u7684\u5de5\u5177\u89e3\u51b3\uff0c\u800c\u5f88\u591a\u5de5\u5177\u7528\u4e24\u5e74\u5c31\u6dd8\u6c70\uff0c\u5f88\u7cdf\u5fc3\u3002</p>\n<p>\u7ee7\u7eed\u5f00\u53d1\u53bb\u4e86\u563f\u563f</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/xuejiangavvo32", 
        "name": "xuejiangavvo32", 
        "avatar": "https://cdn.v2ex.com/gravatar/0af55aea9da8cea99c727f3ae4fff939?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/1094141", 
      "date_modified": "2024-12-01T11:10:13+00:00", 
      "content_html": "<p>\u8bf4\u5230\u5efa\u7ad9\u8fd9\u4e2a\u4e8b\u60c5\uff0c\u4f5c\u4e3a\u5f00\u53d1\u8005\u7684\u4f60\u53ef\u4ee5\u6709\u975e\u5e38\u591a\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u66f4\u4f55\u51b5\u662f 2024 \u5e74\u4e86\uff0c\u5efa\u7ad9\u4ea4\u7ed9 AI \u4e5f\u80fd\u5feb\u901f\u5b8c\u6210\u3002\u7528 WordPress \u5f00\u6e90\u7cfb\u7edf\uff0c\u7528 Wix \u3001SXL \u7b49 SaaS \u5e73\u53f0\uff0c\u6216\u8005\u76f4\u63a5\u201cRails new\"\u4ece\u96f6\u642d\u5efa\u3002</p>\n<p>\u672c\u6587\u5c06\u4e3a\u4f60\u4ecb\u7ecd\u4e00\u4e2a\u5efa\u7ad9\u65b0\u8303\u5f0f\uff1aBaklib \u3002Baklib \u662f\u7528 Rails \u6846\u67b6\u6784\u5efa\u7684\u57fa\u4e8e Liquid \u8bed\u8a00\u7684\u6a21\u7248\u5efa\u7ad9\u5e73\u53f0\uff0c\u4f5c\u4e3a Ruby/Rails \u5f00\u53d1\u8005\uff0c\u8fd9\u9053\u83dc\u5e94\u8be5\u518d\u719f\u6089\u4e0d\u8fc7\u4e86\u3002</p>\n<h2>1. \u6ce8\u518c Baklib \u8d26\u53f7</h2>\n<p>\u8d26\u53f7\u6ce8\u518c\u5730\u5740\uff1a <a href=\"https://baklib.com/get-started\" rel=\"nofollow\">https://baklib.com/get-started</a></p>\n<p>\u9996\u5148\u54b1\u4eec\u9700\u8981\u5728 Baklib \u4e0a\u6ce8\u518c\u4e00\u4e2a\u7ec4\u7ec7\u7ba1\u7406\u8005\u8d26\u53f7\uff08\u514d\u8d39\u7684\uff09\u3002\u5f53\u4f60\u6ce8\u518c\u597d\u4e00\u4e2a\u7ec4\u7ec7\u7ba1\u7406\u8005\u8d26\u53f7\u767b\u5f55\u5230\u7ec4\u7ec7\u540e\u53f0\u4ee5\u540e\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5728\u7ec4\u7ec7\u7ba1\u7406\u7aef\u6709\u4e00\u4e2a\u6a21\u677f\u7ba1\u7406\uff0c\u70b9\u51fb\u5373\u53ef\u8fdb\u5165\u5230\u7ec4\u7ec7\u6a21\u677f\u7ba1\u7406\u4e2d\u5fc3\u3002</p>\n<p>*** \u5982\u679c\u63d0\u793a\u8bd5\u7528\u7248\u672c\uff0c\u5219\u8054\u7cfb\u5ba2\u670d\u6ce8\u660e\u6765\u81ea V2EX \u7533\u8bf7\u514d\u8d39\u7248\u672c ***</p>\n<p><img alt=\"\" class=\"embedded_image\" loading=\"lazy\" referrerpolicy=\"no-referrer\" rel=\"noreferrer\" src=\"https://l.ruby-china.com/photo/wedxt/cd432cd3-8289-4740-ae10-53c89e530bbb.png%21large\"/></p>\n<h2>2. \u6dfb\u52a0\u7f51\u7ad9\u6a21\u677f</h2>\n<p>Baklib \u4e0a\u7684\u6a21\u677f\u90fd\u662f\u5f00\u6e90\u7684\uff0c\u6258\u7ba1\u5728\uff1a <a href=\"https://gitlab.com/baklib/themes\" rel=\"nofollow\">https://gitlab.com/baklib/themes</a></p>\n<p>\u4f60\u53ef\u4ee5\u505a\u516c\u5171\u6a21\u677f\u4e2d\u9009\u62e9\u559c\u6b22\u7684\u6a21\u677f\uff0c\u590d\u5236 git \u94fe\u63a5\u5e76\u6dfb\u52a0\u5230 Baklib \u4e0a\uff0c\u4e5f\u53ef\u4ee5\u53c2\u8003 Baklib \u7684\u6a21\u677f\u5f00\u53d1\u8981\u6c42\uff0c\u81ea\u884c\u6253\u9020\u6743\u9650\u7684\u6a21\u677f\u3002\u5177\u4f53\u53c2\u8003\uff1aBaklib \u6a21\u677f\u5f00\u53d1\u4e2d\u5fc3</p>\n<h2>3. \u5b89\u88c5\u7ad9\u70b9</h2>\n<p>\u5728 [\u5e02\u573a] \u4e2d\u53ef\u4ee5\u770b\u5230\u6240\u6709\u516c\u5171\u7684\u6a21\u677f\uff0c\u4ee5\u53ca\u7ec4\u7ec7\u81ea\u5df1\u6302\u8f7d\u7684\u6a21\u677f\uff0c\u9009\u62e9\u5b89\u88c5\uff0c\u6839\u636e\u6d41\u7a0b\u5373\u53ef\u521b\u5efa\u4e00\u4e2a\u7ad9\u70b9\u3002</p>\n<p><img alt=\"\" class=\"embedded_image\" loading=\"lazy\" referrerpolicy=\"no-referrer\" rel=\"noreferrer\" src=\"https://l.ruby-china.com/photo/wedxt/36112dcc-4b7d-4132-b1b2-66091d454811.png%21large\"/></p>\n<h2>4. \u7ad9\u70b9\u7ba1\u7406</h2>\n<p>\u4e00\u65e6\u521b\u5efa\u597d\u4e00\u4e2a\u7ad9\u70b9\uff0c\u5c31\u53ef\u4ee5\u6709\u4e09\u4e2a\u5165\u53e3\uff1a\u524d\u7aef\u4f1a\u81ea\u52a8\u751f\u6210\u4e00\u4e2a\u72ec\u7acb\u57df\u540d\u7684\u7f51\u7ad9\uff08\u53ef\u89e3\u6790\u5230\u81ea\u6709\u57df\u540d\uff09\uff0c\u540e\u53f0\u6709\u4e2a\u72ec\u7acb\u7684\u7f51\u7ad9\u5185\u5bb9\u7ba1\u7406\u7aef\uff0c\u4ee5\u53ca\u6a21\u677f\u5728\u7ebf\u7f16\u8f91\u5668\u3002</p>\n<p><img alt=\"\" class=\"embedded_image\" loading=\"lazy\" referrerpolicy=\"no-referrer\" rel=\"noreferrer\" src=\"https://l.ruby-china.com/photo/wedxt/decf3273-09bb-427d-ad56-cef8b1e9a421.png%21large\"/></p>\n<blockquote>\n<p>\u53c2\u8003\u7528\u6b64\u6a21\u677f\u521b\u5efa\u7684\u771f\u5b9e\u6848\u4f8b\uff1a <a href=\"https://release.baklib.cn\" rel=\"nofollow\">https://release.baklib.cn</a></p>\n</blockquote>\n<h2>5. \u6a21\u677f\u5f00\u53d1</h2>\n<p>\u91cd\u5934\u620f\u662f\u5bf9\u6a21\u677f\u7684\u4e8c\u6b21\u5f00\u53d1\u652f\u6301\uff0cBaklib \u8bbe\u8ba1\u4e86\u4e00\u4e2a\u7075\u6d3b\u7684\u7f51\u7ad9\u6a21\u677f\u7ed3\u6784\uff0c\u4f60\u53ef\u4ee5\u968f\u65f6\u5728\u7ebf\u5b9e\u65f6\u5f00\u53d1\u3001\u5b9e\u65f6\u9884\u89c8\uff0c\u5305\u62ec\u590d\u6742\u7684\u81ea\u5b9a\u4e49\u5b57\u6bb5\u3001\u6392\u7248\u5e03\u5c40\u3001\u67e5\u8be2\u68c0\u7d22\u7b49\u80fd\u529b\u3002</p>\n<p>\u6a21\u677f\u7ed3\u6784</p>\n<pre><code class=\"language-ruby\">\n\u251c\u2500\u2500 assets\n    \u2514\u2500\u2500 images\n    \u2514\u2500\u2500 css\n    \u2514\u2500\u2500 javascripts\n    \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 config\n    \u2514\u2500\u2500 settings_schema.json\n\u251c\u2500\u2500 layout\n    \u2514\u2500\u2500 theme.liquid\n\u251c\u2500\u2500 locales\n\u251c\u2500\u2500 src\n\u251c\u2500\u2500 statics\n\u251c\u2500\u2500 snippets\n\u2514\u2500\u2500 templates\n</code></pre>\n<p>\u9759\u6001\u6587\u4ef6\u53ef\u76f4\u63a5\u6dfb\u52a0\u5230 statics \u76ee\u5f55\u4e2d\uff0c\u6bd4\u5982\u6dfb\u52a0\u4e00\u4e2a about.liquid \uff0c\u76f4\u63a5\u524d\u7aef\u8f93\u5165\u5730\u5740\uff1a <code>/s/about</code> \u5373\u53ef\u6253\u5f00\u3002\n\u6a21\u677f\u7247\u6bb5\u6dfb\u52a0\u5230 snippets \u76ee\u5f55\u4e2d\uff0c\u6bd4\u5982\u6dfb\u52a0\u6587\u4ef6 <code>_header.liquid</code>\uff0c\u5728\u5176\u4ed6\u6587\u4ef6\u5f15\u7528\uff1a<code> {% render 'header' %}</code>\u3002</p>\n<p>\u6a21\u677f\u6587\u4ef6\u6dfb\u52a0\u5230 templates \u76ee\u5f55\u4e2d\uff0c\u6bd4\u5982\u6dfb\u52a0\u6587\u4ef6 blog.liquid</p>\n<h4>\u6a21\u677f\u4ee3\u7801</h4>\n<p>\u6bcf\u4e2a\u6a21\u677f\u7684\u9875\u5185\u4ee3\u7801\u7531 HTML \uff08 CSS/JS \uff09 + Liquid \u7ec4\u6210\uff0c\u4ee5\u4e0b\u662f\u6a21\u677f\u9996\u9875\u4ee3\u7801\u793a\u4f8b\uff1aindex.liquid</p>\n<p><code>{% assign pages = site.pages['/'].children_in_list  %}</code></p>\n<pre><code class=\"language-html\">\n&lt;div class=\"overflow-visible h-auto pb-[70px] min-h-screen bg-slate-100\"&gt;\n\n  &lt;div class=\"max-w-5xl mx-auto relative  flex flex-col sm:flex-row sm:space-x-2 px-3 sm:px-0  pt-[220px]\"&gt;\n    &lt;div class=\"w-full space-y-2 lg:space-y-4 -mt-[60px]\"&gt;\n      {% paginate_tag pages, per: 6 %}\n        {% for page in pages %}\n          {% render \"card\", page: page %}\n        {% else %}\n          {{ 'generic.empty' | t }}\n        {% endfor %}\n        {% render 'paginate', paginate: paginate %}\n      {% endpaginate_tag %}\n    &lt;/div&gt;\n\n    &lt;!-- Sidebar Section --&gt;\n    &lt;aside class=\"hidden w-64 pl-4 sm:block shrink-0\"&gt;\n      {% render 'sidebar', site: site %}\n    &lt;/aside&gt;\n  &lt;/div&gt;\n&lt;/div&gt;\n\n{% schema %}\n  {\n      \"name\": \"Index\",\n      \"description\": \"Card Style\",\n      \"thumb_url\": \"images/theme/index-card.png\",\n      \"sub_page_templates\": [\"page\"]\n  }\n{% endschema %}\n\n</code></pre>\n<h4>\u81ea\u5b9a\u4e49\u6a21\u677f\u5b57\u6bb5</h4>\n<p>\u5982\u679c\u9700\u8981\u81ea\u5b9a\u4e49\u6a21\u677f\u9875\u9762\u7684\u5b57\u6bb5\uff0c\u5219\u53ea\u9700\u8981\u505a\u6a21\u677f\u9875\u9762\u7684 schame \u4e2d\u58f0\u660e\u5373\u53ef\u3002</p>\n<pre><code class=\"language-ruby\">\"settings\": [\n  {\n    \"id\": \"tags\",\n    \"type\": \"tag_picker\",\n    \"multiple\": true,\n    \"label\": \"\u6807\u7b7e\"\n  },\n</code></pre>\n<p>Baklib \u652f\u6301 18+ \u52a8\u6001\u8868\u5355\uff08\u89c1 <a href=\"https://dev.baklib.cn/2a32/forms\" rel=\"nofollow\">https://dev.baklib.cn/2a32/forms</a>\uff09\uff0c\u8db3\u4ee5\u6ee1\u8db3\u5404\u79cd\u7c7b\u578b\u5b57\u6bb5\u7684\u81ea\u5b9a\u4e49\u3002</p>\n", 
      "date_published": "2024-12-01T11:09:46+00:00", 
      "title": "\u624b\u628a\u624b\u6559\u60a8\u5728 Baklib \u4e0a\u642d\u5efa\u4e00\u4e2a\u6a21\u677f\u7f51\u7ad9", 
      "id": "https://www.v2ex.com/t/1094141"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/WildCat", 
        "name": "WildCat", 
        "avatar": "https://cdn.v2ex.com/avatar/baf2/9ae7/39784_large.png?m=1710948175"
      }, 
      "url": "https://www.v2ex.com/t/1062335", 
      "title": "\u6211\u56de\u6765\u4e86\uff0c Ruby on Rails", 
      "id": "https://www.v2ex.com/t/1062335", 
      "date_published": "2024-08-03T20:46:09+00:00", 
      "content_html": "<a target=\"_blank\" href=\"https://blog.wildcat.io/2024/08/i-m-back-rails-zh/\" rel=\"nofollow noopener\">https://blog.wildcat.io/2024/08/i-m-back-rails-zh/</a>"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/cxhello", 
        "name": "cxhello", 
        "avatar": "https://cdn.v2ex.com/avatar/a0f8/5a7f/651579_large.png?m=1769489720"
      }, 
      "url": "https://www.v2ex.com/t/1033505", 
      "title": "Ruby on Rails \u56fd\u5185\u4f7f\u7528\u60c5\u51b5", 
      "id": "https://www.v2ex.com/t/1033505", 
      "date_published": "2024-04-18T02:09:15+00:00", 
      "content_html": "<ul>\n<li>Ruby on Rails \u6846\u67b6\u5982\u4f55\uff1f</li>\n<li>\u73b0\u5728\u5b66\u4e60\u662f\u5426\u8fd8\u6709\u5fc5\u8981\uff1f</li>\n<li>\u662f\u5426\u63a8\u8350\u5de5\u4f5c\u4e2d\u4f7f\u7528\uff1f</li>\n</ul>\n<p>\u6b22\u8fce\u5404\u4f4d V \u53cb\u524d\u6765\u63a2\u8ba8\u3002</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/dw2693734d", 
        "name": "dw2693734d", 
        "avatar": "https://cdn.v2ex.com/avatar/fbcf/03e0/601784_large.png?m=1702109329"
      }, 
      "url": "https://www.v2ex.com/t/991400", 
      "date_modified": "2023-11-13T03:32:35+00:00", 
      "content_html": "<p>Rails \u5199\u7684\uff0c\u57fa\u672c\u4e0a\u505a\u5230\u4e86 no code \u548c\u5f3a\u7075\u6d3b\u6027</p>\n<p>\u9002\u5408\u81ea\u5df1\u7684\u9879\u76ee\u4e4b\u4e0a\u505a\u96c6\u6210</p>\n<p><a href=\"https://github.com/motor-admin/motor-admin\" rel=\"nofollow\">https://github.com/motor-admin/motor-admin</a></p>\n", 
      "date_published": "2023-11-13T03:29:51+00:00", 
      "title": "\u63a8\u8350\u4e00\u4e2a Admin Panel", 
      "id": "https://www.v2ex.com/t/991400"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/zzzzxl", 
        "name": "zzzzxl", 
        "avatar": "https://cdn.v2ex.com/avatar/1a25/8a66/489783_large.png?m=1602290305"
      }, 
      "url": "https://www.v2ex.com/t/877398", 
      "title": "\u5f53\u6211\u66f4\u6362 mac m2 \u82af\u7247 \u65e0\u6cd5\u4f7f\u7528\u4f7f\u7528 mysql2 \u62a5\u9519 symbol not found in flat namespace (_mysql_affected_rows)", 
      "id": "https://www.v2ex.com/t/877398", 
      "date_published": "2022-09-03T02:02:19+00:00", 
      "content_html": "<p>Rails \u7248\u672c <code>7.0.3</code></p>\n<p>MySQL \u7248\u672c <code>5.7.29</code></p>\n<p>Ruby  \u7248\u672c <code>3.1.1</code></p>\n<p>Rvm   \u7248\u672c <code>1.29.12</code></p>\n<p>mysql2 \u7248\u672c <code>~&gt; 0.5</code></p>\n<p>\u6211\u7684\u9879\u76ee\u6b63\u5728\u5c1d\u8bd5\u8fc1\u79fb m2 \u82af\u7247,\u5f53\u6211\u5c1d\u8bd5\u8fd0\u884c<code>rails s</code>\u65f6 \u51fa\u73b0\u4e86\u4ee5\u4e0b\u9519\u8bef</p>\n<pre><code class=\"language-bash\">`require': dlopen(/Users/list/.rvm/rubies/ruby-3.1.1/lib/ruby/gems/3.1.0/gems/mysql2-0.5.4/lib/mysql2/mysql2.bundle, 0x0009): symbol not found in flat namespace (_mysql_affected_rows)\n</code></pre>\n<p>\u6211\u5c1d\u8bd5\u8fc7\u4ee5\u4e0b\u89e3\u51b3\u65b9\u6848\uff0c\u90fd\u4e0d\u80fd\u89e3\u51b3</p>\n<pre><code class=\"language-bash\">bundle config build.mysql2 \"--with-ldflags=-L/usr/local/mysql/lib --with-cppflags=-I/usr/local/mysql/include\"\n</code></pre>\n<pre><code class=\"language-bash\"> gem install mysql2 -v '0.5' -- --with-mysql-config=/usr/local/mysql/bin/mysql_config --with-ldflags=\"-L/usr/local/mysql/lib -L$(brew --prefix openssl)/lib\" --with-cppflags=-I$(brew --prefix openssl)/include\n</code></pre>\n<p>\u8bf7\u95ee\u5982\u4f55\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898?</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/gamesover", 
        "name": "gamesover", 
        "avatar": "https://cdn.v2ex.com/gravatar/6bbbc78a70fcb3621e68d4b2630d8900?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/839954", 
      "title": "\u540e\u7aef\u6536\u5230\u4e24\u6b21\u91cd\u590d api \u8bf7\u6c42\uff0c\u5982\u4f55\u5224\u65ad\u7b2c\u4e8c\u6b21\u662f\u91cd\u590d\u7684\uff1f", 
      "id": "https://www.v2ex.com/t/839954", 
      "date_published": "2022-03-12T16:02:08+00:00", 
      "content_html": "<p>\u6211\u4eec\u6709\u4e2a\u6bd4\u8f83\u53e4\u8001\u7684 app \uff0c\u524d\u7aef\u662f ember \uff0c\u540e\u7aef\u662f rails</p>\n<p>\u4ee5\u524d\u4e00\u76f4\u90fd\u597d\u597d\uff0c\u6700\u8fd1\u9047\u5230 2 \u6b21\uff0c\u540e\u7aef\u6536\u5230\u8c8c\u4f3c\u91cd\u590d\u7684 api post \u8bf7\u6c42</p>\n<p>\u9664\u4e86\u8bf7\u6c42\u7684\u53d1\u9001\u7684\u65f6\u95f4\u4e0d\u540c\uff0c\u6570\u636e\u4f20\u8fc7\u6765\u662f\u4e00\u6a21\u4e00\u6837\u7684</p>\n<p>\u540e\u7aef\u6709\u6ca1\u6709\u529e\u6cd5\u5224\u65ad\u51fa\u662f chrome \u81ea\u52a8\u628a api request \u91cd\u590d\u53d1\u9001\u4e86\u4e00\u904d\uff0c\u6709\u8fd9\u79cd\u53ef\u80fd\u5417</p>\n<p>\u8fd8\u662f\u8bf4\u7528\u6237\u53c8\u70b9\u4e86\u4e00\u6b21\u63d0\u4ea4\u6309\u94ae</p>\n<p>\u4f46\u7167\u7406\uff0c\u63d0\u4ea4\u6309\u94ae\u70b9\u4e00\u6b21\u540e\u5c31 disable \u4e86\u554a\uff0c\u5b9e\u5728\u4e0d\u61c2\u4e3a\u4ec0\u4e48\u4f1a\u51fa\u73b0\u8fd9\u79cd\u60c5\u51b5</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/Koell", 
        "name": "Koell", 
        "avatar": "https://cdn.v2ex.com/avatar/b7fa/d16c/65139_large.png?m=1740122610"
      }, 
      "url": "https://www.v2ex.com/t/823065", 
      "title": "Rails 7 \u53d1\u5e03", 
      "id": "https://www.v2ex.com/t/823065", 
      "date_published": "2021-12-18T17:09:19+00:00", 
      "content_html": "Ruby on Rails scales from HELLO WORLD to IPO.<br /><br /><a target=\"_blank\" href=\"https://rubyonrails.org/2021/12/15/Rails-7-fulfilling-a-vision\" rel=\"nofollow noopener\">https://rubyonrails.org/2021/12/15/Rails-7-fulfilling-a-vision</a><br /><br />\u524d\u7aef\u9ed8\u8ba4 importmap \uff0c\u518d\u4e5f\u6ca1\u6709\u4ec0\u4e48 npm \u3001node_modules \uff0c\u642d\u914d hotwire \u5168\u5bb6\u6876\u5f00\u542f\u524d\u7aef\u65b0\u4f53\u9a8c\u3002<br />\u8001\u4f20\u7edf\u52a0\u5f3a\u7248\uff0c\u4ece\u96f6\u5236\u4f5c\u4e00\u4e2a\u5e26\u5b9e\u65f6\u8bc4\u8bba\u7684\u535a\u5ba2<br /><div class=\"embedded_video_wrapper\"><iframe src=\"https://www.youtube.com/embed/mpWFrUwAN88\" class=\"embedded_video\" allowfullscreen=\"\" type=\"text/html\" id=\"ytplayer\" frameborder=\"0\"></iframe></div>"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/zzyyqq", 
        "name": "zzyyqq", 
        "avatar": "https://cdn.v2ex.com/gravatar/d9c8bdc8d44b9f7c100d627f1cef1424?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/821750", 
      "title": "\u5927\u5bb6\u5199 ruby on rails applications \u7684\u65f6\u5019\u4e00\u822c\u600e\u4e48\u5199\u524d\u7aef\u9875\u9762?", 
      "id": "https://www.v2ex.com/t/821750", 
      "date_published": "2021-12-12T20:10:07+00:00", 
      "content_html": "<p>\u662f\u7528 ror \u81ea\u5e26\u7684\u524d\u7aef\u6846\u67b6\uff1f<br/>\n\u8fd8\u662f\u518d\u81ea\u5df1\u5199\u4e00\u4e2a rn/angular/vue \u524d\u7aef\u5e94\u7528\u7136\u540e\u8ba9 ror \u4f5c\u4e3a\u540e\u53f0\uff1f<br/>\n\u8c22\u8c22</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/zzyyqq", 
        "name": "zzyyqq", 
        "avatar": "https://cdn.v2ex.com/gravatar/d9c8bdc8d44b9f7c100d627f1cef1424?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/821444", 
      "title": "\u5982\u4f55\u52a8\u6001\u663e\u793a\u548c\u4fdd\u5b58\u4e00\u7cfb\u5217\u8f93\u5165\u6846\u4e2d\u7684\u5185\u5bb9", 
      "id": "https://www.v2ex.com/t/821444", 
      "date_published": "2021-12-10T15:52:09+00:00", 
      "content_html": "<p>hello </p>\n<pre><code>\u60f3\u95ee\u4e00\u4e2a\u5173\u4e8e ror \u4e0a\u524d\u53f0\u52a8\u6001\u663e\u793a\u8f93\u5165\u6846\u4e2a\u6570\u7684\u95ee\u9898\u3002\n</code></pre>\n<p>\u6bd4\u5982\u6211\u6307\u5b9a\u4e00\u4e2a\u6570\u5b57 10, \u90a3\u4e48\u524d\u53f0\u5c31\u663e\u793a 10 \u4e2a\u8f93\u5165\u6846\uff0c\u70b9\u51fb\u63d0\u4ea4\u540e\uff0c\u5c31\u628a\u8fd9\u662f\u4e2a\u7528\u6237\u8f93\u5165\u7684\u503c\u53d1\u9001\u7ed9\u540e\u53f0\u5e76\u4f5c\u4e3a list \u5b58\u50a8\u5728\u672c\u5730. <br/></p>\n<p>\u5982\u679c\u6211\u6307\u5b9a\u4e00\u4e2a\u6570\u5b57 30 \uff0c \u90a3\u4e48\u6d41\u7a0b\u76f8\u540c\u4f46\u662f\u663e\u793a\u7ed9\u524d\u53f0\u4e09\u5341\u4e2a\u8f93\u5165\u6846\u3002 <br/></p>\n<p>\u627e\u4e86\u4e00\u5708\u597d\u50cf\u6ca1\u53d1\u73b0\u5728 ror \u4e0a\u6709\u4ec0\u4e48\u6bd4\u8f83\u7b80\u5355\u7684\u529e\u6cd5\u3002 <br/></p>\n<p>\u8fd8\u671b\u8d50\u6559\u3002\u591a\u8c22\u3002</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/0c0c0f", 
        "name": "0c0c0f", 
        "avatar": "https://cdn.v2ex.com/gravatar/83ee8a7198a1869a0c3120a5624a87a2?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/806875", 
      "title": "ruby on rails: no implicit conversion of nil into String", 
      "id": "https://www.v2ex.com/t/806875", 
      "date_published": "2021-10-10T11:07:02+00:00", 
      "content_html": "Controller \u4ee3\u7801<br />class CveController &lt; ApplicationController<br />  def index<br />    @<a target=\"_blank\" href=\"/member/cves\" rel=\"nofollow noopener\">cves</a> = Cve.all<br />  end<br /><br />  def show<br />    @<a target=\"_blank\" href=\"/member/cve\" rel=\"nofollow noopener\">cve</a> = Cve.find_by(cve_id: params[:cve_id])<br />  end<br />end<br /><br /><br />\u5f02\u5e38\u4fe1\u606f<br />Showing app/views/cve/index.html.erb where line #3 raised:<br /><br />no implicit conversion of nil into String<br />Extracted source (around line #3):<br />        <br />&lt;h1&gt;Cve#index&lt;/h1&gt;<br />&lt;p&gt;Find me in app/views/cve/index.html.erb&lt;/p&gt;<br />&lt;% @<a target=\"_blank\" href=\"/member/cves\" rel=\"nofollow noopener\">cves</a>.each do |cve| %&gt;<br />    &lt;tr&gt;<br />      &lt;td&gt;&lt;%= cve.cve_id %&gt;&lt;/td&gt;<br />      &lt;td&gt;&lt;%= cve.summary %&gt;&lt;/td&gt;<br /><br />Rails.root: /Users/admin/RubyProjects/xx-api<br /><br />Application Trace | Framework Trace | Full Trace<br />app/views/cve/index.html.erb:3<br />Request<br />Parameters:<br /><br />None<br />Toggle session dump<br />Toggle env dump<br />Response<br />Headers:<br /><br />None"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/pythonee", 
        "name": "pythonee", 
        "avatar": "https://cdn.v2ex.com/avatar/4b6e/52b7/29622_large.png?m=1642211709"
      }, 
      "url": "https://www.v2ex.com/t/766398", 
      "title": "Rails \u73b0\u5728\u56fd\u5185\u662f\u4e0d\u662f\u6709\u70b9\u51c9\u4e86\uff1f", 
      "id": "https://www.v2ex.com/t/766398", 
      "date_published": "2021-03-30T02:28:19+00:00", 
      "content_html": ""
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/ChrisZou", 
        "name": "ChrisZou", 
        "avatar": "https://cdn.v2ex.com/avatar/0940/09fb/204426_large.png?m=1605153594"
      }, 
      "url": "https://www.v2ex.com/t/735974", 
      "title": "Rails 6.1 \u5347\u7ea7\u8bb0\u5f55", 
      "id": "https://www.v2ex.com/t/735974", 
      "date_published": "2020-12-16T04:52:33+00:00", 
      "content_html": "<p>\u671f\u5f85\u5df2\u4e45\u7684 Rails 6.1 \u7ec8\u4e8e\u53d1\u5e03\u4e86\u3002\u8d81\u7740\u53cc\u4f11\uff0c\u7ed9\u6211\u7684\u7684\u5c0f\u5f00\u6e90\u9879\u76ee\u4ece Rails6.0 \u5347\u7ea7\u5230\u4e86 6.1\uff0c\u8bb0\u5f55\u5728\u6b64 <a href=\"https://chriszou.com/2020/12/16/geekweibo-upgrade-to-rails-6-1/\" rel=\"nofollow\">https://chriszou.com/2020/12/16/geekweibo-upgrade-to-rails-6-1/</a></p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/ChrisZou", 
        "name": "ChrisZou", 
        "avatar": "https://cdn.v2ex.com/avatar/0940/09fb/204426_large.png?m=1605153594"
      }, 
      "url": "https://www.v2ex.com/t/727307", 
      "title": "\u4f7f\u7528 Vue \u524d\u7aef\u3001Rails \u540e\u7aef\u5b9e\u73b0\u56fe\u7247\u4e0a\u4f20\u7684\u529f\u80fd", 
      "id": "https://www.v2ex.com/t/727307", 
      "date_published": "2020-11-19T14:19:39+00:00", 
      "content_html": "<p>\u6b63\u6587\u89c1 <a href=\"https://chriszou.com/2020/11/16/upload-image-using-vue-and-rails/\" rel=\"nofollow\">https://chriszou.com/2020/11/16/upload-image-using-vue-and-rails/</a><br/>\n\u6838\u5fc3\u65b9\u6cd5\u662f\u4f7f\u7528 formData \u4f5c\u4e3a ajax \u7684 body\uff0c\u4e4b\u524d\u4e3b\u8981\u4e0d\u6e05\u695a\u7684\u70b9\u5728\u4e8e csrf token \u7684\u4f20\u9012\u3002<br/>\n\u5f53\u7136\uff0c\u8fd9\u91cc\u7684\u65b9\u6cd5\u53ef\u80fd\u4e0d\u662f\u6700\u597d\u7684\u3002\u5982\u679c\u54ea\u4f4d\u5927\u795e\u6709\u66f4\u597d\u7684\u65b9\u6cd5\u5b9e\u73b0\uff0c\u8fd8\u8bf7\u4e0d\u541d\u6307\u6559\uff01</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/wewin", 
        "name": "wewin", 
        "avatar": "https://cdn.v2ex.com/avatar/5c2a/ce37/227221_large.png?m=1606373092"
      }, 
      "url": "https://www.v2ex.com/t/725665", 
      "date_modified": "2020-11-16T02:45:31+00:00", 
      "content_html": "<p>\u4e3b\u8981\u5b9e\u73b0\u7684\u529f\u80fd\uff1a\u5177\u6709\u53d1\u5e03\u53ef\u4f1a\u9762\u65f6\u95f4\u6743\u9650\u7684\u7528\u6237 A\uff0c\u767b\u5f55\u7cfb\u7edf\u53d1\u5e03\u53ef\u4f1a\u9762\u65f6\u95f4\u3002\u4e0e\u4f1a\u8005 B\uff0c\u767b\u5f55\u7cfb\u7edf\u4ece A \u53d1\u5e03\u7684\u65f6\u95f4\u4e2d\u9009\u62e9\u81ea\u5df1\u53ef\u4ee5\u53c2\u89c1\u4f1a\u8bae\u7684\u65f6\u95f4\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u8fbe\u6210\u4e00\u4e2a\u4f1a\u8bae\u9080\u7ea6\u3002</p>\n<p>\u94fe\u63a5\uff1a<a href=\"http://calendar.mayihahaha.com/\" rel=\"nofollow\">http://www.calendar.com/</a></p>\n<p>\u6d4b\u8bd5\u8d26\u53f7\uff1a</p>\n<p>A \u7c7b\u7528\u6237\uff1aYoyo / 123456\nB \u7c7b\u7528\u6237\uff1aAda / 123456</p>\n", 
      "date_published": "2020-11-16T02:36:37+00:00", 
      "title": "\u5199\u4e86\u4e2a\u5728\u7ebf\u7ea6\u4f1a\u7684\u65e5\u5386\uff0c\u5df2\u7ecf\u90e8\u7f72\u5728\u516c\u6709\u4e91\u4e0a\u4e86\uff0c\u6b63\u6587\u6709\u8bbf\u95ee\u94fe\u63a5", 
      "id": "https://www.v2ex.com/t/725665"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/coool", 
        "name": "coool", 
        "avatar": "https://cdn.v2ex.com/gravatar/dd999e8cb14d94112f57c94fb5654906?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/723965", 
      "date_modified": "2020-11-11T04:13:08+00:00", 
      "content_html": "<blockquote>\n<p>\u8fd9\u662f\u524d\u4e24\u5929\u5f00\u7684\u5e16\uff1a<a href=\"https://www.v2ex.com/t/723318\" rel=\"nofollow\">https://www.v2ex.com/t/723318</a></p>\n</blockquote>\n<p>\u6211\u7684\u5de5\u4f5c\u662f Go \u5f00\u53d1\uff0c\u56e0\u4e3a\u603b\u542c\u8bf4 Ruby \u3001Rails \u5f88\u540a\uff0c\u6240\u4ee5\u4e1a\u4f59\u6253\u7b97\u5b66\u5b66\uff0c\u9009\u4e86\u300a Agile web development with Rails 6 \u300b\u4e00\u4e66\u770b\u7684\uff0c\u6298\u817e\u4e86 3 \u5929\u51c6\u5907\u653e\u5f03\u4e86\uff0c\u771f\u7684\u4e0d\u503c\u4e00\u5b66\u3002</p>\n<p>\u5982\u679c\u4e00\u9879\u7f16\u7a0b\u8bed\u8a00\u7684\u5165\u95e8\uff0c\u5927\u91cf\u65f6\u95f4\u8981\u82b1\u5230\u6298\u817e\u73af\u5883\u3001\u5404\u79cd\u4e71\u4e03\u516b\u7cdf\u7684\u62a5\u9519\u4e0a\u800c\u65e0\u6cd5\u805a\u7126\u5230\u8bed\u8a00\u3001\u6846\u67b6\u672c\u8eab\uff0c\u90a3\u8fd8\u8c08\u4ec0\u4e48\u63d0\u9ad8\uff1f</p>\n<p>\u5f53\u521d\u5b66 Go \u4e5f\u5c31\u5c0f\u534a\u5929\u642d\u4e86\u73af\u5883\u5c31\u5f00\u59cb\u5199\u4e86\uff0cRails \u6574\u4e86 3 \u5929\uff0c\u6bcf\u5929\u5341\u4e2a\u5c0f\u65f6\uff0c\u5230\u73b0\u5728<code>rails new demo</code>\u90fd\u6ca1\u8dd1\u8d77\u6765\uff0c\u786e\u5207\u7684\u8bf4\u662f\u6ca1\u5b8c\u5168\u8dd1\u8d77\u6765\u3002</p>\n<p><a href=\"https://ruby-china.org/wiki/install_ruby_guide\" rel=\"nofollow\">\u5b89\u88c5 Ruby \u3001Rails</a>\u5c31\u4e0d\u8bf4\u4e86\uff0c<code>rails new demo</code>\u5404\u79cd\u62a5\u9519\uff0c\u6700\u540e<code>localhost:3000</code>\u8bbf\u95ee\u5230\u4e86\uff0c\u4f46\u662f\u81ea\u4ece\u6267\u884c\n\u4e86<code>bin/rails generate controller Say hello goodbye</code>\uff0c\u5386\u6570\u6211\u9047\u5230\u7684\u5404\u79cd\u5947\u602a\u7684\u62a5\u9519\uff0c\u5b8c\u5168\u6ca1\u6709\u4efb\u4f55\u89e3\u51b3\u65b9\u6848\uff1a</p>\n<ul>\n<li><strong>\u6bd4\u5982\u6267\u884c<code>bin/webpack-dev-server</code>\u62a5\u9519\uff1a</strong></li>\n</ul>\n<pre><code>node:internal/modules/cjs/loader:903\n  throw err;\n  ^\n\nError: Cannot find module 'webpack-cli/bin/config-yargs'\nRequire stack:\n</code></pre>\n<p>\u5b98\u65b9 github issure \u5404\u79cd\u8bf4\u7248\u672c\u95ee\u9898\uff0c\u8fd8\u8ba9\u5728<code>packge.json</code>\u52a0\u4e86<code>scripts:</code>\u4ee3\u7801\uff0c\u6362\u6210<code>webpack serve</code>\u5565\u7684\uff0c\u6ca1\u70b9\u7528\uff0c\u6211\u5c31\u5947\u602a\u4e86\u524d\u7aef\u5708\u5404\u79cd\u8f6f\u4ef6\u5e93\u5565\u7684\u5347\u7ea7\u4ece\u6765\u4e0d\u8003\u8651\u5411\u540e\u517c\u5bb9\u5417\uff1f\u7ea6\u5b9a\u7684\u547d\u4ee4\u8bf4\u6539\u5c31\u6539\uff0c\u6539\u4e86\u8fd8\u6ca1\u5565\u7528\uff0c\u89e3\u51b3\u4e0d\u4e86\u65e7\u95ee\u9898\u8fd8\u5236\u9020\u4e00\u5806\u65b0\u95ee\u9898\u3002github \u3001stack overflow \u3001csdn \u4e4b\u6d41\u90fd\u6ca1\u6709\u4efb\u4f55\u89e3\u51b3\u65b9\u6848\uff1a<a href=\"https://github.com/webpack/webpack-dev-server/issues/2759\" rel=\"nofollow\">https://github.com/webpack/webpack-dev-server/issues/2759</a>, <a href=\"https://blog.csdn.net/Piconjo/article/details/105744808\" rel=\"nofollow\">https://blog.csdn.net/Piconjo/article/details/105744808</a></p>\n<ul>\n<li>\n<p><strong>\u6bd4\u5982<code>Cannot find module '@rails/webpacker'</code>\u62a5\u9519\uff1a</strong></p>\n<ul>\n<li>\u5c9b\u56fd\u7684,\u6ca1\u70b9\u7528:<a href=\"https://qiita.com/MosamosaPoodle/items/e051d0a8921314f5f9ed\" rel=\"nofollow\">https://qiita.com/MosamosaPoodle/items/e051d0a8921314f5f9ed</a></li>\n</ul>\n</li>\n<li>\n<p><strong>\u6bd4\u5982<code>rails new --webpack fails with \"Don't know how to build task 'webpacker:install'\"</code>\u62a5\u9519:</strong></p>\n<ul>\n<li><a href=\"https://github.com/rails/webpacker/issues/61\" rel=\"nofollow\">https://github.com/rails/webpacker/issues/61</a> \u6ca1\u70b9\u7528</li>\n<li><a href=\"https://github.com/makandra/katapult/issues/13\" rel=\"nofollow\">https://github.com/makandra/katapult/issues/13</a> \u6ca1\u70b9\u7528</li>\n</ul>\n</li>\n<li>\n<p><strong>\u6bd4\u5982<code>Getting undefined method 'javascript_pack_tag' for</code>\u62a5\u9519\uff1a</strong></p>\n<ul>\n<li><a href=\"https://github.com/rails/webpacker/issues/172\" rel=\"nofollow\">https://github.com/rails/webpacker/issues/172</a> \u6ca1\u70b9\u7528</li>\n</ul>\n</li>\n<li>\n<p><strong>\u6bd4\u5982<code>Command \"webpack\" not found</code>\u62a5\u9519\uff1a</strong></p>\n<ul>\n<li><a href=\"https://github.com/rails/webpacker/issues/522\" rel=\"nofollow\">https://github.com/rails/webpacker/issues/522</a> \u6ca1\u70b9\u7528</li>\n<li><a href=\"https://stackoverflow.com/questions/44845143/webpack-command-not-found\" rel=\"nofollow\">https://stackoverflow.com/questions/44845143/webpack-command-not-found</a>\u6ca1\u70b9\u7528</li>\n</ul>\n</li>\n<li>\n<p><strong>\u6bd4\u5982<code>ActionView::Template::Error: Webpacker can't find application in /app/public/packs/manifest.json</code>\u62a5\u9519\uff1a</strong></p>\n</li>\n</ul>\n<p>\u2026<br/>\n\u2026\u2026\u2026\u2026<br/>\n\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026<br/>\n\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026</p>\n<ul>\n<li>\n<p><strong>\u552f\u4e00\u4e00\u4e2a\u89e3\u51b3\u7684\u95ee\u9898\u662f\u6267\u884c<code>bin/rails generate controller Say hello goodbye</code>\u6ca1\u5565\u53cd\u5e94\uff0c\u7528\u4e86<code>spring stop</code></strong></p>\n</li>\n<li>\n<p><strong>\u73b0\u5728\u6211\u7684 rails \u662f\u8fd9\u6837\u7684\uff1a</strong></p>\n</li>\n</ul>\n<pre><code>$ bin/rails about\n\nAbout your application's environment\nRails version             6.0.3.4\nRuby version              ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]\nRubyGems version          3.1.4\nRack version              2.2.3\nMiddleware                Webpacker::DevServerProxy, ActionDispatch::HostAuthorization, Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, ActiveSupport::Cache::Strategy::LocalCache::Middleware, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, ActionDispatch::RemoteIp, Sprockets::Rails::QuietAssets, Rails::Rack::Logger, ActionDispatch::ShowExceptions, WebConsole::Middleware, ActionDispatch::DebugExceptions, ActionDispatch::ActionableExceptions, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ContentSecurityPolicy::Middleware, Rack::Head, Rack::ConditionalGet, Rack::ETag, Rack::TempfileReaper\nApplication root          /Users/coool/ruby/work/demo\nEnvironment               development\nDatabase adapter          sqlite3\nDatabase schema version   0\n</code></pre>\n<p><strong><code>package.json</code>\u6587\u4ef6\u662f\u8fd9\u6837\u7684</strong>\uff1a</p>\n<pre><code class=\"language-json\">{\n  \"name\": \"demo\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@rails/actioncable\": \"^6.0.0\",\n    \"@rails/activestorage\": \"^6.0.0\",\n    \"@rails/ujs\": \"^6.0.0\",\n    \"turbolinks\": \"^5.2.0\",\n    \"webpack\": \"^5.4.0\"\n  },\n  \"scripts\": {\n    \"serve\": \"webpack serve\"\n  },\n  \"version\": \"0.1.0\",\n  \"devDependencies\": {\n    \"webpack-cli\": \"^4.2.0\",\n    \"webpack-dev-server\": \"^3.11.0\"\n  },\n  \"babel\": {\n    \"presets\": [\n      \"./node_modules/@rails/webpacker/package/babel/preset.js\"\n    ]\n  },\n  \"browserslist\": [\n    \"defaults\"\n  ]\n}\n</code></pre>\n<p>\u53ef\u80fd Rails \u786e\u5b9e\u662f\u6bbf\u5802\u7ea7\u7684\u6846\u67b6\uff0c\u4f46\u662f\u8fd9\u4e2a\u6846\u67b6\u7684\u95e8\u69db\u5728\u4e91\u4e0a\uff0c\u6211\u5728\u5730\u4e0a\u4e0a\u4e0d\u53bb\u2026\u2026\u5404\u79cd\u73af\u5883\u3001\u5347\u7ea7\u3001\u4ee3\u7406\u8bbe\u7f6e\u3001global \u7ffb\u5899\u90fd\u6ca1\u7528\u3001\u7248\u672c\u4e0d\u517c\u5bb9\u3001\u4e71\u4e03\u516b\u7cdf\u7684\u62a5\u9519\uff0c\u662f\u6211\u5728\u5199 Go \u7684\u65f6\u5019\u4ece\u6765\u6ca1\u6709\u9047\u5230\u8fc7\u7684\u3002</p>\n<p>\u53e6\u5916\u5410\u69fd\u4e00\u4e0b Ruby-China \u771f\u7684\u2026\u2026\u4e0d\u77e5\u9053\u6709\u591a\u5c11\u4eba\u7684\u8010\u5fc3\u662f 7 \u5929\uff0c\u53cd\u6b63\u6211\u8fd9\u4e09\u5929\uff0c\u6bcf\u5929\u5341\u51e0\u4e2a\u5c0f\u65f6\u7684\u6298\u817e\u8fd9\u4e9b\u62a5\u9519\u5df2\u7ecf\u8017\u5c3d\u4e86\u8010\u5fc3\uff0c\u653e\u5f03\u4e86\u3002</p>\n", 
      "date_published": "2020-11-11T04:12:49+00:00", 
      "title": "Ruby, Rails \u4e0d\u503c\u4e00\u5b66", 
      "id": "https://www.v2ex.com/t/723965"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/coool", 
        "name": "coool", 
        "avatar": "https://cdn.v2ex.com/gravatar/dd999e8cb14d94112f57c94fb5654906?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/723318", 
      "title": "Rails new \u547d\u4ee4\u4e00\u76f4\u8f6c\u5708\u600e\u4e48\u529e\uff1f", 
      "id": "https://www.v2ex.com/t/723318", 
      "date_published": "2020-11-09T10:47:01+00:00", 
      "content_html": "<p>\u5927\u4f6c\u4eec\uff0c\u6267\u884c<code>rails new demo</code>\u547d\u4ee4\u65f6\u5230\u4e0b\u9762\u8fd9\u91cc\u4e00\u76f4\u5728\u8f6c\u5708\uff0c\u5f88\u4e45\u4e5f\u4e0d\u5f80\u4e0b\u8d70\uff0c\u6c42\u6307\u70b9\uff1a</p>\n<pre><code>warning @rails/webpacker &gt; webpack &gt; watchpack &gt; watchpack-chokidar2 &gt; chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.\nwarning @rails/webpacker &gt; webpack &gt; watchpack &gt; watchpack-chokidar2 &gt; chokidar &gt; fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.\nwarning @rails/webpacker &gt; webpack &gt; micromatch &gt; snapdragon &gt; source-map-resolve &gt; resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated\nwarning @rails/webpacker &gt; webpack &gt; micromatch &gt; snapdragon &gt; source-map-resolve &gt; urix@0.1.0: Please see https://github.com/lydell/urix#deprecated\n[2/4] \ud83d\ude9a  Fetching packages...\n[3/4] \ud83d\udd17  Linking dependencies...\n[4/4] \ud83d\udd28  Building fresh packages...\n[-/3] \u2802 waiting...\n[-/3] \u2802 waiting...\n[3/3] \u2802 node-sass\n</code></pre>\n<p>\u5c31\u662f\u6700\u540e\u4e09\u884c\uff0c\u4e00\u76f4\u5728\u8f6c\u5708\uff1a</p>\n<pre><code>[-/3] \u2802 waiting...\n[-/3] \u2802 waiting...\n[3/3] \u2802 node-sass\n</code></pre>\n<p>\u5df2\u7ecf\u7528\u4e0b\u9762\u8fd9\u4e24\u4e2a\u547d\u4ee4\u6362\u4e86\u4ee3\u7406\uff1a</p>\n<pre><code>gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/\n\nbundle config mirror.https://rubygems.org https://gems.ruby-china.com\n</code></pre>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/xiqingongzi", 
        "name": "xiqingongzi", 
        "avatar": "https://cdn.v2ex.com/avatar/41a4/f16b/57504_large.png?m=1670285486"
      }, 
      "url": "https://www.v2ex.com/t/642476", 
      "date_modified": "2020-02-06T13:51:05+00:00", 
      "content_html": "Heroku \uff1f\u8fd8\u662f\u5565\uff0c\u611f\u89c9\u9879\u76ee\u8fd8\u6ca1\u6709\u8db3\u591f\u89c4\u6a21\u7684\u65f6\u5019\uff0c\u4e0d\u592a\u60f3\u641e vps \u8dd1\u3002", 
      "date_published": "2020-02-06T03:55:46+00:00", 
      "title": "\u5927\u5bb6\u90fd\u7528\u4ec0\u4e48\u6765\u90e8\u7f72 ROR \u7684\uff1f", 
      "id": "https://www.v2ex.com/t/642476"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/diegobona", 
        "name": "diegobona", 
        "avatar": "https://cdn.v2ex.com/avatar/1dd0/3cc6/186570_large.png?m=1470913198"
      }, 
      "url": "https://www.v2ex.com/t/642414", 
      "date_modified": "2020-02-06T00:03:46+00:00", 
      "content_html": "<p>\u6700\u8fd1\u5b85\u5728\u5bb6\u597d\u597d\u7528\u4e86\u4e00\u4e0b\uff0c\u771f\u7684\u662f\u65e0\u4ee5\u8a00\u8868\u554a\u3002\n\u4ee3\u7801\u91cf\n\u4f18\u96c5\u7684\u8bed\u6cd5\n......\n\u4e0d\u591a\u8bf4\u4e86\uff0c\u8c01\u8bd5\u8c01\u77e5\u9053\u3002</p>\n", 
      "date_published": "2020-02-05T15:44:38+00:00", 
      "title": "ruby on rails \u505a web \u5f00\u53d1\uff0c\u6548\u7387\u771f\u662f\u6760\u6760\u7684\u554a", 
      "id": "https://www.v2ex.com/t/642414"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/charlie21", 
        "name": "charlie21", 
        "avatar": "https://cdn.v2ex.com/gravatar/5765a702fda4ba24599890b4c40cc2de?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/579947", 
      "date_modified": "2019-07-04T04:39:06+00:00", 
      "content_html": "<p><a href=\"https://mvnrepository.com/artifact/org.springframework.roo/org.springframework.roo.addon.web.mvc.jsp\" rel=\"nofollow\">https://mvnrepository.com/artifact/org.springframework.roo/org.springframework.roo.addon.web.mvc.jsp</a></p>\n<p>\u8fd9\u662f\u4e00\u4e2a\u7ea2\u6781\u4e00\u65f6\u7684 Java Spring Framework \u7684\u63d2\u4ef6\uff0c\u63d0\u4f9b\u4e86 ROO shell\uff0c\u51e0\u4e4e\u662f<a href=\"https://www.quora.com/Between-Spring-Roo-and-Spring-Boot-which-one-is-a-better-choice-for-making-a-web-app\" rel=\"nofollow\">\u5b8c\u5168\u7167\u642c ror \u7684\u601d\u8def</a>\u3002</p>\n<p>\u4f46\u662f \u5b83\u7684\u6700\u540e\u66f4\u65b0\u65e5\u671f\u662f 2015\u3002\u7b80\u5355\u7684\u8bf4\u5c31\u662f\u5b83\u6b7b\u4e86\u3002\u4f7f\u7528\u5b83\u7684\u5f00\u53d1\u8005\u6d3b\u8dc3\u5728 2010 ~ 2016 \u5e74\uff1b\u4e5f\u5c31\u662f \u5728\u5b83\u4e0d\u518d\u66f4\u65b0\u4e4b\u540e\u7684\u4e00\u5e74\u4e4b\u5185\uff0c\u6574\u4e2a\u76d8\u5b50\u7684\u547d\u8fd0\u5c31\u662f\u4eba\u8d70\u8336\u51c9 ( \u800c\u4e14 \u5bf9\u4e8e roo \u7684\u539f\u521b\u8005\u800c\u8a00\u5176\u5b9e\u662f\u6ca1\u6709\u4efb\u4f55\u635f\u5931\u7684\u5427\uff0c\u4ed6\u4e0d\u7528\u5bf9 roo \u8d1f\u8d23\uff0c\u4ed6\u8bf4\u4e0d\u5199\u5c31\u4e0d\u5199\u4e86  \u4ed6\u8bf4\u4e0d\u66f4\u65b0\u4e86\u90a3\u5c31\u4e0d\u66f4\u65b0\u4e86\uff0c\u9664\u975e\u4ed6\u80fd\u4e13\u95e8\u62db\u8058\u62db\u6765\u4eba\u66ff\u4ed6\u5199 ( \u6210\u7acb\u4e00\u4e2a\u516c\u53f8 \u5199 roo \u76c8\u5229 \u62db\u4eba \u5199 roo \u76c8\u5229 \u6269\u62db\uff0c\u4fdd\u6301 roo \u7684\u4e0d\u6b7b )\uff0c\u4f46\u662f\u4ed6\u6ca1\u6709\u3002\u7ed3\u679c\u5c31\u662f roo \u5b83\u6b7b\u4e86 \u548c \u6574\u4e2a\u76d8\u5b50\u7684\u4eba\u8d70\u8336\u51c9\u3002roo \u7684\u5f00\u53d1\u8005\u5708\u5b50\u4e5f\u5c31\u6563\u4e86 )\u3002</p>\n<p>\u90a3\u4e48\u6211\u5c31\u8981\u95ee\u4e86\uff0c\u5982\u679c\u6709\u4e00\u5929 DHH \u6ca1\u6709\u518d\u7ef4\u62a4 ror \u4e86\u600e\u4e48\u529e\uff1f</p>\n<p>( \u8fd9\u662f\u4e00\u4e2a\u5047\u8bbe\u6027\u95ee\u9898\u3002\u4e50\u610f\u8c08\u5462\u5c31\u5728\u8fd9\u4e2a\u5047\u8bbe\u4e0b\u8c08\uff0c\u8c22\u8c22\uff0c\u4e0d\u559c\u6b22\u8c08\u8c08\u8fd9\u4e2a\u5047\u8bbe\u90a3\u5c31\u522b\u8c08\uff0c\u628a\u5b83\u7559\u7ed9\u60f3\u8c08\u7684\u4eba   )</p>\n", 
      "date_published": "2019-07-04T04:29:55+00:00", 
      "title": "\u5982\u679c\u6709\u4e00\u5929 DHH \u6ca1\u6709\u518d\u7ef4\u62a4 ror \u4e86\u600e\u4e48\u529e\uff1f", 
      "id": "https://www.v2ex.com/t/579947"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/leelds", 
        "name": "leelds", 
        "avatar": "https://cdn.v2ex.com/gravatar/d4a7247799d563942739ccc7478dc220?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/562742", 
      "title": "Ruby on Rails \u600e\u4e48\u6837\uff1f", 
      "id": "https://www.v2ex.com/t/562742", 
      "date_published": "2019-05-10T01:42:33+00:00", 
      "content_html": "<p>\u6709\u6ca1\u6709\u5c0f\u4f19\u4f34\u7528\u8fc7\uff08\u5b9e\u9645\u5f00\u53d1\u8fc7 1 \u4e00\u5e74\u4ee5\u4e0a\u7684\uff09\uff0c\u672c\u4eba\u60f3\u5165\u5751\n\u5165\u5751\u524d\u603b\u662f\u6709\u70b9\u5c0f\u5fd0\u5fd1\uff0c\u6240\u4ee5\u3002\u3002\u3002</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/tsaoyu", 
        "name": "tsaoyu", 
        "avatar": "https://cdn.v2ex.com/avatar/ee19/2ce9/73677_large.png?m=1632794909"
      }, 
      "url": "https://www.v2ex.com/t/552602", 
      "title": "\u4e16\u754c\u65e0\u4eba\u5e06\u8239\u9526\u6807\u8d5b\uff0c\u62db\u52df\u4e24\u540d Ruby \u5fd7\u613f\u8005\u7684\u53c2\u4e0e", 
      "id": "https://www.v2ex.com/t/552602", 
      "date_published": "2019-04-06T16:34:46+00:00", 
      "content_html": "<p>\u5404\u4f4d Ruby \u5f00\u53d1\u8005\u5927\u5bb6\u597d\uff0c</p>\n<p>\u6211\u4eec\u662f\u7b2c 12 \u5c4a\u4e16\u754c\u65e0\u4eba\u5e06\u8239\u9526\u6807\u8d5b\u7684\u7ec4\u59d4\uff0c\u4eca\u5e74\u6211\u4eec\u9996\u6b21\u5c06\u8fd9\u9879\u56fd\u9645\u578b\u7684\u8d5b\u4e8b\u5e26\u5230\u4e86\u4e2d\u56fd\u4e3e\u529e\u3002\u672c\u5730\u6bd4\u8d5b\u4f1a\u7531\u6d59\u6c5f\u5927\u5b66\u5728\u6d59\u6c5f\u7701\u5b81\u6ce2\u5e02\u4e3e\u529e\uff0c\u5c4a\u65f6\u4e16\u754c\u5404\u5730\u7684\u65e0\u4eba\u5e06\u8239\u53c2\u8d5b\u961f\u4f0d\u4f1a\u5728\u4e2d\u56fd\u53c2\u4e0e\u89d2\u9010\u4eca\u5e74\u7684\u5404\u4e2a\u5956\u9879\u3002</p>\n<p><img src=\"https://i.imgur.com/XBDgG2n.jpg\" alt=\"\"></p>\n<p>\u4f5c\u4e3a\u5f00\u6e90\u4e16\u754c\u7684\u7231\u597d\u8005\u4ee5\u53ca\u6301\u7eed\u8d21\u732e\u8005\uff0c\u6211\u4eec\u7ec4\u59d4\u4f1a\u6bcf\u5e74\u90fd\u4f1a\u4e0e\u5f53\u5730\u7684\u5f00\u6e90\u7231\u597d\u8005\u4e00\u8d77\uff0c\u5171\u540c\u5b8c\u6210\u517c\u5177\u8da3\u5473\u6027\u4e0e\u7ade\u6280\u6027\u7684\u5404\u9879\u6311\u6218\u3002\u8239\u8236\u8ffd\u8e2a\u7cfb\u7edf\u4f5c\u4e3a\u8d5b\u4e8b\u7684\u6838\u5fc3\u7cfb\u7edf\uff0c\u5728\u6bcf\u5e74\u7684\u6bd4\u8d5b\u4e2d\u7684\u5b9e\u65f6\u8d5b\u679c\u5c55\u793a\u548c\u8d5b\u540e\u81ea\u52a8\u8bc4\u5206\u4e2d\u90fd\u8d77\u5230\u4e86\u91cd\u8981\u7684\u4f5c\u7528\u3002\u4eca\u5e74\u5728\u4e2d\u56fd\u7684\u6bd4\u8d5b\u4e2d\uff0c\u6211\u4eec\u5e0c\u671b\u7ee7\u7eed\u5f00\u5c55\u548c\u5f53\u5730\u7231\u597d\u8005\u7684\u5408\u4f5c\uff0c\u5728\u4ee5\u4e0b\u51e0\u4e2a\u9886\u57df\u4e2d\u8fdb\u4e00\u6b65\u4f18\u5316\u8239\u8236\u8ffd\u8e2a\u7cfb\u7edf\u3002\u5176\u4e2d\u4e3b\u8981\u7684\u5de5\u4f5c\u5185\u5bb9\u6709\u4e24\u4e2a\u65b9\u9762\uff1a</p>\n<p>\u670d\u52a1\u5668\u7aef\uff1a</p>\n<ul>\n<li>\u5730\u56fe\u672c\u5730\u5316\u3001\u5f00\u6e90\u5316\u4ee5\u66ff\u4ee3\u7cfb\u7edf\u4e2d\u4f7f\u7528\u7684 Google \u5730\u56fe</li>\n<li>\u591a\u8239\u8236\u95f4\u7684\u4f4d\u7f6e\u5171\u4eab API \u5f00\u53d1</li>\n</ul>\n<p>\u79fb\u52a8\u7aef\uff1a</p>\n<ul>\n<li>\u8239\u8236\u81ea\u52a8\uff0c\u624b\u52a8\u72b6\u6001\u88c1\u5224\u7cfb\u7edf\uff08\u5411\u670d\u52a1\u5668\u62a5\u544a\u4f55\u65f6\u8239\u8236\u5904\u4e8e\u81ea\u52a8\u63a7\u5236\uff0c\u4f55\u65f6\u5904\u4e8e\u624b\u52a8\u907f\u969c\u72b6\u6001\uff09</li>\n<li>\u5b9e\u65f6\u8d5b\u679c\u67e5\u8be2\u4e0e\u5206\u4eab\u529f\u80fd</li>\n</ul>\n<p><img src=\"https://i.imgur.com/ra03ykE.jpg\" alt=\"\"></p>\n<p>\u5982\u679c\u4f60\u6709\u5174\u8da3\u53c2\u4e0e\u5230\u6211\u4eec\u4e2d\u95f4\u6765\uff0c\u8bf7\u53d1\u9001\u90ae\u4ef6\u5230 tsaoyu at gmail dot com</p>\n<p>GitHub Repository at <a href=\"https://github.com/WRSC/tracking\" rel=\"nofollow\">https://github.com/WRSC/tracking</a></p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/Caojx", 
        "name": "Caojx", 
        "avatar": "https://cdn.v2ex.com/gravatar/a5f784b91c79b6f344069c2b1bb068af?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/518075", 
      "date_modified": "2018-12-16T12:44:12+00:00", 
      "content_html": "rails \u7248\u672c 5.2.2<br />require 'test_helper'<br /><br />class SayControllerTest &lt; ActionDispatch::IntegrationTest<br />  test \"should get hello\" do<br />    get say_hello_url<br />    assert_response :success<br />  end<br />  test \"should say hello in json\" do<br />    get say_hello_url<br />    assert_equal \"{\\\"hello\\\":\\\"Rails!\\\"}\", @<a target=\"_blank\" href=\"/member/response\" rel=\"nofollow\">response</a>.body<br />  end<br />  test \"should say hello in json\" do<br />    get say_hello_url,{'user'=&gt;\"Join\"}<br />    assert_equal \"{\\\"hello\\\":\\\"Join!\\\"}\", @<a target=\"_blank\" href=\"/member/response\" rel=\"nofollow\">response</a>.body<br />  end<br />end", 
      "date_published": "2018-12-16T12:43:49+00:00", 
      "title": "\u6b63\u5728\u770b restful rail development \u8fd9\u672c\u4e66\uff0c\u6309\u7167\u4e66\u4e0a\u5199\u7684\u6d4b\u8bd5\u62a5\u9519\u4e86\uff0c\u5927\u4f6c\u5e2e\u6211\u770b\u770b", 
      "id": "https://www.v2ex.com/t/518075"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/versionzhang", 
        "name": "versionzhang", 
        "avatar": "https://cdn.v2ex.com/gravatar/d1bdaeaed006b1635f5e95b905fb245f?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/483731", 
      "title": "spree \u7535\u5546\u6846\u67b6\u600e\u4e48\u6837", 
      "id": "https://www.v2ex.com/t/483731", 
      "date_published": "2018-08-27T10:23:44+00:00", 
      "content_html": "<p>\u6700\u8fd1\u5728\u7814\u7a76 rails \u4e0b\u7684 spree \u7535\u5546\u6846\u67b6\uff0c\u6709\u6ca1\u6709 v \u53cb\u4f7f\u7528\u8fc7\uff0c\u5206\u4eab\u4e00\u4e0b\u4f7f\u7528\u7ecf\u9a8c\u6216\u8005\u5fc3\u5f97\uff0c\u8c22\u8c22</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/Andor_Chen", 
        "name": "Andor_Chen", 
        "avatar": "https://cdn.v2ex.com/avatar/0402/5959/339_large.png?m=1680834107"
      }, 
      "url": "https://www.v2ex.com/t/432147", 
      "title": "\u9001\u51e0\u672c\u300aRails 5 \u654f\u6377\u5f00\u53d1\u300b", 
      "id": "https://www.v2ex.com/t/432147", 
      "date_published": "2018-02-24T03:13:31+00:00", 
      "content_html": "<p><img alt=\"Rails 5 \u654f\u6377\u5f00\u53d1\" src=\"http://wx1.sinaimg.cn/mw690/62870481gy1forcmocpmpj20h40lnn2n.jpg\"></p>\n<p>\u300a Agile Web Development with Rails 5 \u300b\u4e00\u4e66\u7684<a href=\"https://about.ac/books/agile-rails5/\" rel=\"nofollow\">\u4e2d\u6587\u7248</a>\u5df2\u4e8e\u5e74\u524d\u4e0a\u5e02\uff01</p>\n<p>\u672c\u4e66\u7531<strong>\u534e\u4e2d\u79d1\u6280\u5927\u5b66\u51fa\u7248\u793e</strong>\u5f15\u8fdb\uff0c\u611f\u8c22\u51fa\u7248\u793e\u548c\u7f16\u8f91\u5bf9 Ruby/Rails \u7684\u5173\u6ce8\uff01\u672c\u4e66\u7531<strong>\u6211\u548c chinakr</strong> \u5408\u8bd1\uff0c\u611f\u8c22 chinakr \u7684\u8f9b\u52e4\uff01\u672c\u4e66\u7531<strong>\u5927\u7586 Ruby \u6280\u672f\u56e2\u961f</strong>\u5ba1\u6821\uff0c\u7279\u6b64\u611f\u8c22\uff01</p>\n<hr>\n<p>\u300a Rails 5 \u654f\u6377\u5f00\u53d1\u300b\u8363\u83b7 Jolt \u6280\u672f\u56fe\u4e66\u5927\u5956\u3002\u672c\u4e66\u4ee5\u8bb2\u89e3\u201c\u8d2d\u4e66\u7f51\u7ad9\u201d\u6848\u4f8b\u4e3a\u4e3b\u7ebf\uff0c\u9010\u6b65\u4ecb\u7ecd Rails \u7684\u5185\u7f6e\u529f\u80fd\u3002\u5168\u4e66\u5206\u4e3a 3 \u90e8\u5206\uff0c\u7b2c\u4e00\u90e8\u5206\u4ecb\u7ecd Rails \u7684\u5b89\u88c5\u3001\u5e94\u7528\u7a0b\u5e8f\u9a8c\u8bc1\u3001Rails \u6846\u67b6\u7684\u4f53\u7cfb\u7ed3\u6784\uff0c\u4ee5\u53ca Ruby \u8bed\u8a00\u77e5\u8bc6\uff1b\u7b2c\u4e8c\u90e8\u5206\u7528\u8fed\u4ee3\u65b9\u5f0f\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\uff0c\u7136\u540e\u4f9d\u636e\u654f\u6377\u5f00\u53d1\u6a21\u5f0f\u5f00\u5c55\u6d4b\u8bd5\uff0c\u6700\u540e\u7528 Capistrano \u5b8c\u6210\u90e8\u7f72\uff1b\u7b2c\u4e09\u90e8\u5206\u8865\u5145\u65e5\u5e38\u5b9e\u7528\u7684\u5f00\u53d1\u77e5\u8bc6\u3002\u672c\u4e66\u65e2\u6709\u76f4\u89c2\u7684\u793a\u4f8b\uff0c\u53c8\u6709\u6df1\u5165\u7684\u5206\u6790\uff0c\u540c\u65f6\u6db5\u76d6\u4e86 Web \u5f00\u53d1\u5404\u65b9\u9762\u7684\u77e5\u8bc6\uff0c\u582a\u79f0\u4e00\u90e8\u5185\u5bb9\u5168\u9762\u800c\u53c8\u6df1\u5165\u6d45\u51fa\u7684\u4f73\u4f5c\u3002\u7b2c 5 \u7248\u589e\u52a0\u4e86\u5173\u4e8e Rails 5 \u548c Ruby 2.2 \u65b0\u7279\u6027\u548c\u6700\u4f73\u5b9e\u8df5\u7684\u5185\u5bb9\u3002</p>\n<hr>\n<p>\u597d\u4e86\uff0c\u91cd\u70b9\u6765\u4e86\u3002\u719f\u6089\u6211\u7684\u8bfb\u8005\u77e5\u9053\uff0c\u6bcf\u9022\u6211\u7ffb\u8bd1\u7684\u4e66\u4e0a\u5e02\uff0c\u6211\u90fd\u4f1a\u641e\u4e2a\u8d60\u4e66\u6d3b\u52a8\uff0c\u8fd9\u4e00\u6b21\u4e5f\u4e0d\u4f8b\u5916\u3002\u5e74\u524d\u5df2\u7ecf\u9001\u51fa\u4e00\u6ce2\uff0c\u5e74\u540e\u518d\u6765\u4e00\u6ce2\u3002</p>\n<p><img alt=\"\" src=\"http://wx1.sinaimg.cn/mw690/62870481gy1forclrrtkhj20u01azmz6.jpg\"></p>\n<p>\u8bf7\u626b\u63cf\u56fe\u4e2d\u4e8c\u7ef4\u7801\uff0c\u6216\u8005\u957f\u6309\u56fe\u7247\uff0c\u8bc6\u522b\u56fe\u4e2d\u4e8c\u7ef4\u7801\u53c2\u4e0e\u6b64\u6b21\u6d3b\u52a8\u3002</p>\n<hr>\n<p><strong>\u6d3b\u52a8\u7ec6\u8282\uff1a</strong></p>\n<ul>\n<li>\u672c\u6b21\u8d60\u4e66\u7531\u534e\u4e2d\u79d1\u6280\u5927\u5b66\u51fa\u7248\u793e\u63d0\u4f9b\uff0c\u7531\u51fa\u7248\u793e\u5bc4\u9001\uff1b</li>\n<li>\u8bf7\u52ff\u5728\u6b64\u8ba8\u8bba\u4e0e\u672c\u4e3b\u9898\u65e0\u5173\u7684\u8bdd\u9898\uff1b</li>\n<li>\u5171\u8ba1 3 \u672c\uff0c\u6bcf\u4f4d\u4e2d\u5956\u8005 1 \u672c\uff1b</li>\n<li>\u622a\u81f3 2018 \u5e74 2 \u6708 27 \u65e5 12:00:00 \uff08 UTC+8 \uff09\uff1b</li>\n<li>\u83b7\u5956\u8005\u5982\u5728 2018 \u5e74 2 \u6708 28 \u65e5 23:59:59 \uff08 UTC+8 \uff09\u4e4b\u524d\u672a\u63d0\u4f9b\u90ae\u5bc4\u5730\u5740\uff0c\u89c6\u4e3a\u81ea\u52a8\u653e\u5f03\uff1b</li>\n<li>\u5b89\u9053\u4fdd\u7559\u6700\u7ec8\u89e3\u91ca\u6743\u3002</li>\n</ul>\n<hr>\n<p>\u8865\u5145\u94fe\u63a5\uff1a</p>\n<ul>\n<li><a href=\"https://book.douban.com/subject/27615703/\" rel=\"nofollow\">\u8c46\u74e3\u9875\u9762</a></li>\n<li><a href=\"https://detail.tmall.com/item.htm?id=564089292501\" rel=\"nofollow\">\u51fa\u7248\u793e\u7f51\u5e97</a></li>\n<li><a href=\"https://item.jd.com/12281409.html\" rel=\"nofollow\">\u4eac\u4e1c\u81ea\u8425</a></li>\n<li><a href=\"https://www.amazon.cn/dp/B0791WXVBQ/\" rel=\"nofollow\">\u4e9a\u9a6c\u900a</a></li>\n</ul>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/rina", 
        "name": "rina", 
        "avatar": "https://cdn.v2ex.com/avatar/edf1/43e2/108279_large.png?m=1760527393"
      }, 
      "url": "https://www.v2ex.com/t/418224", 
      "date_modified": "2021-04-02T10:04:49+00:00", 
      "content_html": "<h1>\u51c6\u5907\u5de5\u4f5c</h1>\n<ul>\n<li>\u8d2d\u4e70\u57df\u540d\uff1a<a href=\"http://name.com/\" rel=\"nofollow\">http://name.com/</a></li>\n<li>\u8d2d\u4e70\u4e00\u53f0\u4e91\u670d\u52a1\u5668, \u63d0\u4f9b\u5546: \u963f\u91cc\u4e91\uff0cAWS</li>\n<li>\u57df\u540d\u7ed1\u5b9a IP \u4e3a\u670d\u52a1\u5668 IP \u5730\u5740</li>\n</ul>\n<p>\u672c\u6587\u4ecb\u7ecd\u7684\u5185\u5bb9\u4e3a\uff1a\u670d\u52a1\u5668 ubuntu16.04, Rails \u9879\u76ee\uff0cmina \u53d1\u5e03</p>\n<h1>\u5b89\u88c5 rails \u73af\u5883</h1>\n<ul>\n<li>\u4f7f\u7528 root \u8d26\u53f7\u767b\u5f55\u670d\u52a1\u5668\uff0c\u521b\u5efa\u4e00\u4e2a\u6ca1\u6709 root \u6743\u9650\u7684\u8d26\u53f7\u3002</li>\n</ul>\n<pre><code>adduser newuser\n\n</code></pre>\n<p>\u8bbe\u7f6e\u65b0\u7528\u6237\u5bc6\u7801</p>\n<h4>\u914d\u7f6e ssh</h4>\n<p>\u5728\u672c\u5730\u751f\u6210 SSH KEY \uff08\u5982\u679c\u5df2\u7ecf\u6709\u4e86\uff0c\u53ef\u4ee5\u5ffd\u7565\u8fd9\u6b65\u3002\uff09</p>\n<ul>\n<li>\n<p>\u6253\u5f00\u7ec8\u7aef</p>\n</li>\n<li>\n<p>\u7528\u4f60\u81ea\u5df1\u7684\u90ae\u7bb1\u5730\u5740\u66ff\u6362\u4e0b\u9762\u7684\u547d\u4ee4\uff0c\u5e76\u6267\u884c</p>\n</li>\n</ul>\n<pre><code>$ ssh-keygen -t rsa -b 4096 -C \"your_email@example.com\"\n</code></pre>\n<ul>\n<li>\u6267\u884c\u8fd9\u6761\u547d\u4ee4\u65f6\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u4f60\u8f93\u5165\u8981\u4fdd\u5b58\u5bc6\u94a5\u7684\u6587\u4ef6\u4f4d\u7f6e\u53ca\u5b89\u5168 passphrase\uff0c\u8bf7\u6309 Enter \u952e\u5c31\u884c\u4e86\u3002</li>\n</ul>\n<p>\u751f\u6210\u5b8c\u4e4b\u540e\uff0c\u5728 <code>~/.ssh/</code> \u76ee\u5f55\u4e0b\u4f1a\u6dfb\u52a0\u4e24\u4e2a\u6587\u4ef6\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u4e00\u4e2a\u79c1\u94a5 <code>id_rsa</code>, \u4e00\u4e2a\u516c\u94a5 <code>id_rsa.pub</code>.</p>\n<h4>\u914d\u7f6e\u65e0\u5bc6\u7801\u767b\u5f55\u670d\u52a1\u5668</h4>\n<p>\u8fd9\u4e00\u6b65\u662f\u4e3a\u4e86\u7ed9 mina \u53d1\u5e03\u63d0\u4f9b\u65b9\u4fbf\uff0c\u56e0\u4e3a mina \u53d1\u5e03\u9700\u8981\u65e0\u5bc6\u767b\u5f55\u670d\u52a1\u5668\uff0c\u6267\u884c\u53d1\u5e03\u547d\u4ee4\u3002</p>\n<ul>\n<li>\u5c06\u516c\u94a5 <code>id_rsa.pub</code> \u6587\u4ef6\u4e0a\u4f20\u5230\u670d\u52a1\u5668\u4e0a, \u5e76\u6dfb\u52a0\u5230 <code>authorized_keys</code></li>\n</ul>\n<pre><code>$ scp ~/.ssh/id_rsa.pub root@your.domain.com:~/.ssh/\n\n$ ssh root@your.domain.com\n\n$ cd ~/.ssh/\n\n$ cat id_rsa.pub &gt;&gt; authorized_keys\n\n$ rm id_rsa.pub\n\n</code></pre>\n<ul>\n<li>\u91cd\u65b0\u5f00\u4e00\u4e2a\u7ec8\u7aef, \u767b\u5f55\u670d\u52a1\u5668\uff0c\u5982\u679c\u65e0\u9700\u8f93\u5165\u5bc6\u7801\u767b\u5f55\u6210\u529f\uff0c\u90a3\u914d\u7f6e\u4e0a\u9762\u7684\u914d\u7f6e\u5c31\u6210\u529f\u4e86\u3002</li>\n</ul>\n<pre><code>ssh root@your.domain.com\n</code></pre>\n<p>\u4ee5\u4e0a\u662f\u914d\u7f6e <code>root</code> \u7528\u6237\u65e0\u5bc6\u7801\u767b\u5f55\uff0c \u540c\u6837\u7ed9 <code>newuser</code> \u7528\u6237\u914d\u7f6e\u6210\u65e0\u5bc6\u7801\u767b\u5f55\u3002</p>\n<ul>\n<li>\u767b\u5f55 <code>root</code> \u8d26\u53f7\uff0c\u5c06\u670d\u52a1\u5668\u4e0a\u7684 ssh \u914d\u7f6e\u5173\u6389\u5bc6\u7801\u767b\u5f55</li>\n</ul>\n<pre><code>vi /etc/ssh/sshd_config\n\n\u66f4\u65b0\uff1a\n\nPasswordAuthentication no\n\n</code></pre>\n<h4>\u4e3a\u4e86\u786e\u4fdd\u80fd\u987a\u5229\u5b89\u88c5 Rails\uff0c\u5148\u8981\u5b89\u88c5 Node.js \u548c Yarn \u7684\u7cfb\u7edf\u4f9d\u8d56</h4>\n<p>\u4ee5\u4e0b\u64cd\u4f5c\u4f7f\u7528 <code>root</code> \u8d26\u53f7\u6267\u884c</p>\n<pre><code>curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -\ncurl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -\necho \"deb https://dl.yarnpkg.com/debian/ stable main\" | sudo tee /etc/apt/sources.list.d/yarn.list\n\nsudo apt-get update\nsudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev nodejs yarn\n\n</code></pre>\n<h4>\u5b89\u88c5 rbenv</h4>\n<p>\u4ee5\u4e0b\u64cd\u4f5c\u4f7f\u7528 <code>newuser</code> \u8d26\u53f7\u6267\u884c</p>\n<pre><code>cd\ngit clone https://github.com/rbenv/rbenv.git ~/.rbenv\necho 'export PATH=\"$HOME/.rbenv/bin:$PATH\"' &gt;&gt; ~/.bashrc\necho 'eval \"$(rbenv init -)\"' &gt;&gt; ~/.bashrc\nexec $SHELL\n\ngit clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build\necho 'export PATH=\"$HOME/.rbenv/plugins/ruby-build/bin:$PATH\"' &gt;&gt; ~/.bashrc\nexec $SHELL\n\nrbenv install 2.4.3\nrbenv global 2.4.3\nruby -v\n</code></pre>\n<pre><code>gem install bundler\nrbenv rehash\n</code></pre>\n<h4>\u914d\u7f6e git \u8d26\u53f7</h4>\n<p>\u4ee5\u4e0b\u64cd\u4f5c\u4f7f\u7528 <code>newuser</code> \u8d26\u53f7\u6267\u884c</p>\n<ul>\n<li>\u7528\u4f60\u7684 github \u8d26\u53f7\u4fe1\u606f\uff0c\u66ff\u6362\u4e0b\u9762\u7684\u7528\u6237\u540d\u548c\u90ae\u7bb1\uff0c\u5e76\u6267\u884c</li>\n</ul>\n<pre><code>git config --global color.ui true\ngit config --global user.name \"YOUR NAME\"\ngit config --global user.email \"YOUR@EMAIL.com\"\nssh-keygen -t rsa -b 4096 -C \"YOUR@EMAIL.com\"\n</code></pre>\n<p>\u5728\u670d\u52a1\u5668\u4e0a\u751f\u6210\u4e86 ssh key \u540e, \u5c06\u4e0b\u9762\u547d\u4ee4\u8f93\u5165\u7684\u5185\u5bb9\uff0c\u590d\u5236\u540e\u7c98\u8d34\u5230\u4f60 github \u8d26\u53f7<code>SSH and GPG keys</code>\u4e0b\uff1a<a href=\"https://github.com/settings/keys\" rel=\"nofollow\">https://github.com/settings/keys</a></p>\n<pre><code>cat ~/.ssh/id_rsa.pub\n</code></pre>\n<ul>\n<li>\u6d4b\u8bd5 github \u914d\u7f6e\u662f\u5426\u6210\u529f</li>\n</ul>\n<pre><code>ssh -T git@github.com\n</code></pre>\n<p>\u5982\u679c\u6210\u529f\u4f1a\u8f93\u51fa\u4ee5\u4e0b\u4fe1\u606f\uff1a</p>\n<pre><code>Hi kfzyutc! You've successfully authenticated, but GitHub does not provide shell access.\n</code></pre>\n<h4>\u5b89\u88c5 Rails</h4>\n<ul>\n<li>\u4f7f\u7528 <code>newuser</code> \u8d26\u53f7\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4</li>\n</ul>\n<pre><code>$ gem install rails -v 5.1.4\n\n$ rbenv rehash\n\n$ rails -v\n# Rails 5.1.4\n</code></pre>\n<h4>\u5b89\u88c5 MySQL</h4>\n<ul>\n<li>\u4f7f\u7528 <code>root</code> \u8d26\u53f7\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4</li>\n</ul>\n<pre><code>sudo apt-get install mysql-server mysql-client libmysqlclient-dev\n</code></pre>\n<h4>\u5b89\u88c5 PostgreSQL</h4>\n<ul>\n<li>\u4f7f\u7528 <code>root</code> \u8d26\u53f7\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4</li>\n</ul>\n<pre><code>sudo sh -c \"echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' &gt; /etc/apt/sources.list.d/pgdg.list\"\nwget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | sudo apt-key add -\nsudo apt-get update\nsudo apt-get install postgresql-common\nsudo apt-get install postgresql-9.5 libpq-dev\n</code></pre>\n<p>postgres \u5b89\u88c5\u4e0d\u4f1a\u4e3a\u4f60\u8bbe\u7f6e\u4e00\u4e2a\u7528\u6237\uff0c\u6240\u4ee5\u4f60\u9700\u8981\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\u521b\u5efa\u4e00\u4e2a\u6709\u6743\u521b\u5efa\u6570\u636e\u5e93\u7684\u7528\u6237\u3002 \u968f\u610f\u7528\u4f60\u7684\u7528\u6237\u540d\u66ff\u6362 <code>chris</code>\u3002</p>\n<pre><code>sudo -u postgres createuser chris -s\n\n# If you would like to set a password for the user, you can do the following\nsudo -u postgres psql\npostgres=# \\password chris\n\n</code></pre>\n<h1>\u914d\u7f6e nginx</h1>\n<ul>\n<li>\n<p>\u4f7f\u7528 <code>root</code> \u8d26\u53f7\u767b\u5f55\u670d\u52a1\u5668</p>\n</li>\n<li>\n<p>\u5c06 <code>home/newuser/xxx</code>, <code>xxx</code> \u7684\u76ee\u5f55\u6539\u6210\u4f60\u53d1\u5e03\u9879\u76ee\u7684\u76ee\u5f55\uff0c\u5c06 <code><a href=\"http://example.com\" rel=\"nofollow\">example.com</a></code> \u6539\u6210\u4f60\u7684\u57df\u540d\u3002</p>\n</li>\n</ul>\n<pre><code>upstream RBlog {\n  server unix:///home/newuser/xxx/shared/tmp/sockets/puma.sock fail_timeout=0; \n}\n\nserver {\n  listen 80;\n  server_name example.com;\n  root /home/newuser/xxx/current/public;\n\n  location ^~ /assets/ {\n    gzip_static on;\n    expires max;\n    add_header Cache-Control public;\n  }\n\n  location /cable {\n    proxy_http_version 1.1;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection \"Upgrade\";\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_pass http://xxx;\n  }\n\n  location ~ ^/(uploads)/  {\n    expires max;\n    break;\n  }\n\n\n  try_files $uri/index.html $uri @RBlog;\n  location @xxx {\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header Host $http_host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_redirect off;\n    proxy_pass http://xxx;\n  }\n\n  error_page 500 502 503 504 /500.html;\n  client_max_body_size 20M;\n  keepalive_timeout 10;\n}\n\n</code></pre>\n<ul>\n<li>\n<p>\u5c06\u4ee5\u4e0a\u66f4\u6362\u540e\u7684\u914d\u7f6e\u4fe1\u606f\uff0c\u4fdd\u5b58\u5230 <code>/etc/nginx/conf.d/</code> \u76ee\u5f55\u4e0b\uff0c\u547d\u4ee4\u4e3a <code>xxx.conf</code> xxx \u7528\u4f60\u60f3\u8981\u7684\u547d\u540d\u66ff\u6362\u3002</p>\n</li>\n<li>\n<p>\u6d4b\u8bd5\u914d\u7f6e\u4fe1\u606f\u662f\u5426 OK</p>\n</li>\n</ul>\n<pre><code>nginx -t\n# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok\n# nginx: configuration file /etc/nginx/nginx.conf test is successful\n</code></pre>\n<ul>\n<li>\u91cd\u542f nginx</li>\n</ul>\n<pre><code>nginx -s restart\n</code></pre>\n<h1>\u53d1\u5e03 Rails \u9879\u76ee</h1>\n<p>\u5982\u679c\u4f60\u662f\u7528\u8fd9\u4e2a <a href=\"https://github.com/80percent/rails-template\" rel=\"nofollow\">\u6a21\u677f</a> \u521b\u5efa\u7684 Rails \u9879\u76ee, \u4ee5\u4e0b\u914d\u7f6e\u4fe1\u606f\u90fd\u5df2\u7ecf\u6dfb\u52a0\u4e86\uff0c\u53ea\u9700\u8981\u66f4\u65b0\u76ee\u5f55\u4fe1\u606f\u5c31\u884c\u3002</p>\n<p>\u5982\u679c\u6ca1\u6709\u9700\u8981\u5728 Gemfile \u91cc\u6dfb\u52a0\u8fd9\u4e9b gem \u5305\u3002</p>\n<pre><code>gem 'mina', '~&gt;0.3.8', require: false\ngem 'mina-puma', '~&gt;0.3.2', require: false\ngem 'mina-multistage', '~&gt; 1.0', '&gt;= 1.0.2', require: false\ngem 'mina-sidekiq', '~&gt; 0.3.1', require: false\ngem 'mina-logs', '&gt;= 0.1.0', require: false\ngem 'whenever', :require =&gt; false\n</code></pre>\n<h4>\u5728\u4f60\u7684 Rails \u9879\u76ee\u4e0b\u914d\u7f6e puma\uff0c<code>config/puma.rb</code>, \u66ff\u6362 <code>/home/newuser/xxx</code> \u76ee\u5f55.</h4>\n<pre><code>if ENV['RAILS_ENV'] == 'production'\n  app_root = \"/home/newuser/xxx/shared\"\n  pidfile \"#{app_root}/tmp/pids/puma.pid\"\n  state_path \"#{app_root}/tmp/pids/puma.state\"\n  bind \"unix://#{app_root}/tmp/sockets/puma.sock\"\n  activate_control_app \"unix://#{app_root}/tmp/sockets/pumactl.sock\"\n  daemonize true\n  workers 4\n  threads 8, 16\n  preload_app!\n\n  on_worker_boot do\n    ActiveSupport.on_load(:active_record) do\n      ActiveRecord::Base.establish_connection\n    end\n  end\n\n  before_fork do\n    ActiveRecord::Base.connection_pool.disconnect!\n  end\nelse\n  plugin :tmp_restart\nend\n\n</code></pre>\n<h4>\u914d\u7f6e deploy, <code>config/deploy.rb</code></h4>\n<pre><code>set :stages, %w(production staging utcprod)\nset :default_stage, 'staging'\n\nrequire 'mina/multistage'\nrequire 'mina/bundler'\nrequire 'mina/rails'\nrequire 'mina/git'\nrequire 'mina/rbenv'\nrequire 'mina/puma'\nrequire \"mina_sidekiq/tasks\"\nrequire 'mina/logs'\nrequire 'mina/whenever'\n\nset :shared_paths, ['config/database.yml', 'config/newrelic.yml', 'config/application.yml', 'log', 'public/uploads']\n\ntask :environment do\n  invoke :'rbenv:load'\nend\n\ntask :setup =&gt; :environment do\n  queue! %[mkdir -p \"#{deploy_to}/shared/tmp/sockets\"]\n  queue! %[chmod g+rx,u+rwx \"#{deploy_to}/shared/tmp/sockets\"]\n\n  queue! %[mkdir -p \"#{deploy_to}/shared/pids\"]\n  queue! %[chmod g+rx,u+rwx \"#{deploy_to}/shared/pids\"]\n\n  queue! %[mkdir -p \"#{deploy_to}/shared/tmp/pids\"]\n  queue! %[chmod g+rx,u+rwx \"#{deploy_to}/shared/tmp/pids\"]\n\n  queue! %[mkdir -p \"#{deploy_to}/#{shared_path}/log\"]\n  queue! %[chmod g+rx,u+rwx \"#{deploy_to}/#{shared_path}/log\"]\n\n  queue! %[mkdir -p \"#{deploy_to}/#{shared_path}/public/uploads\"]\n  queue! %[chmod g+rx,u+rwx \"#{deploy_to}/#{shared_path}/public/uploads\"]\n\n  queue! %[mkdir -p \"#{deploy_to}/#{shared_path}/config\"]\n  queue! %[chmod g+rx,u+rwx \"#{deploy_to}/#{shared_path}/config\"]\n\n  queue! %[touch \"#{deploy_to}/#{shared_path}/config/application.yml\"]\n  queue  %[echo \"-----&gt; Be sure to edit '#{deploy_to}/#{shared_path}/config/application.yml'\"]\n\n  queue! %[touch \"#{deploy_to}/#{shared_path}/config/database.yml\"]\n  queue  %[echo \"-----&gt; Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml'\"]\nend\n\ndesc \"Deploys the current version to the server.\"\ntask :deploy =&gt; :environment do\n  queue  %[echo \"-----&gt; Server: #{domain}\"]\n  queue  %[echo \"-----&gt; Path: #{deploy_to}\"]\n  queue  %[echo \"-----&gt; Branch: #{branch}\"]\n\n  deploy do\n    invoke :'sidekiq:quiet'\n    invoke :'git:clone'\n    invoke :'deploy:link_shared_paths'\n    invoke :'bundle:install'\n    invoke :'rails:db_migrate'\n    invoke :'rails:assets_precompile'\n    invoke :'deploy:cleanup'\n\n    to :launch do\n      invoke :'puma:hard_restart'\n      invoke :'sidekiq:restart'\n      invoke :'whenever:update'\n    end\n  end\nend\n\ndesc \"Deploys the current version to the server.\"\ntask :first_deploy =&gt; :environment do\n  queue  %[echo \"-----&gt; Server: #{domain}\"]\n  queue  %[echo \"-----&gt; Path: #{deploy_to}\"]\n  queue  %[echo \"-----&gt; Branch: #{branch}\"]\n\n  deploy do\n    invoke :'git:clone'\n    invoke :'deploy:link_shared_paths'\n    invoke :'bundle:install'\n    invoke :'deploy:cleanup'\n\n    to :launch do\n      invoke :'rails:db_create'\n    end\n  end\nend\n</code></pre>\n<h4>\u5728 <code>config/deploy/production.rb</code>\uff0c\u5c06 domain, deploy_to, repository, branch, user \u66ff\u6362\u6210\u4f60\u81ea\u5df1\u7684\u4fe1\u606f\u3002</h4>\n<pre><code>set :domain, 'your.domain.com'\nset :deploy_to, '/home/newuser/xxx'\nset :repository,  'git@github.com:xxx/xxx.git'\nset :branch, 'master'\nset :user, 'newuser'\nset :puma_config, -&gt;{ \"#{deploy_to}/#{current_path}/config/puma/production.rb\" }\n</code></pre>\n<p>\u8fd9\u4e9b\u914d\u7f6e\u4fe1\u606f\u66f4\u65b0\u597d\u4e4b\u540e\uff0c\u63d0\u4ea4\u5230 github</p>\n<h4>\u9996\u6b21\u53d1\u5e03</h4>\n<pre><code>mina setup\nmina first_deploy\n</code></pre>\n<h4>\u540e\u7eed\u53d1\u5e03</h4>\n<pre><code>mina deploy\n</code></pre>\n<h4>\u672c\u5730\u67e5\u770b\u751f\u4ea7\u73af\u5883\u65e5\u5fd7</h4>\n<pre><code>mina log\n</code></pre>\n<h4>\u672c\u5730\u767b\u5f55\u751f\u4ea7\u73af\u5883\u6570\u636e\u5e93\u63a7\u5236\u53f0</h4>\n<pre><code>mina console\n</code></pre>\n<h4>\u672c\u5730\u767b\u5f55\u670d\u52a1\u5668</h4>\n<pre><code>mina ssh\n</code></pre>\n<h1>\u53c2\u8003\u6587\u6863</h1>\n<p>Ubuntu \u5b89\u88c5 Rails \u73af\u5883: <a href=\"https://gorails.com/setup/ubuntu/16.04\" rel=\"nofollow\">https://gorails.com/setup/ubuntu/16.04</a></p>\n<p>Mina \u914d\u7f6e: <a href=\"https://github.com/80percent/rails-template\" rel=\"nofollow\">https://github.com/80percent/rails-template</a></p>\n<p>\u539f\u6587: <a href=\"http://liuzhen.me/articles/17\" rel=\"nofollow\">http://liuzhen.me/articles/17</a></p>\n", 
      "date_published": "2017-12-28T03:13:31+00:00", 
      "title": "Rails \u5e03\u7f72\u6700\u4f73\u5b9e\u8df5", 
      "id": "https://www.v2ex.com/t/418224"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/final0pro", 
        "name": "final0pro", 
        "avatar": "https://cdn.v2ex.com/gravatar/14eee15681631f1db647cf39672a4759?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/392120", 
      "title": "Rails Seed Migration \u95ee\u9898", 
      "id": "https://www.v2ex.com/t/392120", 
      "date_published": "2017-09-19T19:57:35+00:00", 
      "content_html": "<p>\u7ec4\u91cc\u540c\u4e8b\u4e4b\u524d\u5199\u7684 seed migration file, \u5f80\u4e00\u4e2a table X \u91cc\u6dfb\u52a0\u4e86\u4e00\u7cfb\u5217\u6570\u636e\u3002</p>\n<p>\u534a\u5e74\u4e4b\u540e\uff0c\u53e6\u5916\u4e00\u4e2a\u540c\u4e8b\u5728 Object X \u91cc\u52a0\u5165\u4e86 validation</p>\n<p>\u8fd9\u6837\u5c31\u4f1a\u5bfc\u81f4\uff0c\u5728\u672c\u5730\u6211\u91cd\u65b0\u4ece\u5934\u6267\u884c\u811a\u672c <code>rake db:drop; rake db:create; rake db:migrate;</code>\uff0c\u5c31\u4f1a\u56e0\u4e3a\u4e4b\u524d\u7684 seed \u6587\u4ef6\u5728\u6dfb\u52a0\u6570\u636e\u7684\u65f6\u5019\u4f1a\u8c03\u7528 validation\uff0c\u7136\u540e\u5374\u5931\u8d25\u4e86</p>\n<p>\u4ec0\u4e48\u624d\u662f\u6b63\u786e\u7684\u65b9\u6cd5\u5199 seed migration\u3002\u7981\u6b62\u4e00\u5207 callback \u5417\uff1f</p>\n<p>\u8c22\u8c22</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/vzyw", 
        "name": "vzyw", 
        "avatar": "https://cdn.v2ex.com/avatar/daf2/febd/132931_large.png?m=1743169832"
      }, 
      "url": "https://www.v2ex.com/t/379215", 
      "title": "\u5fc3\u597d\u7d2f ruby \u53d1\u4e00\u4e2a OAuth1.0 \u7684\u8bf7\u6c42\u600e\u4e48\u8fd9\u4e48\u96be", 
      "id": "https://www.v2ex.com/t/379215", 
      "date_published": "2017-07-31T04:39:49+00:00", 
      "content_html": "\u76ee\u524d\u7684\u60c5\u51b5\u662f \r<br />1.\u7528 postmen \u81ea\u5e26\u7684 oauth1.0 \u529f\u80fd\u53ef\u4ee5\u8bf7\u6c42\u6210\u529f\r<br />2.\u7528\u81ea\u5df1\u5199\u7684\u7b7e\u540d\u65b9\u6cd5 get \u8bf7\u6c42\u53ef\u4ee5\u6210\u529f\r<br />3.\u7528\u81ea\u5df1\u5199\u7684\u7b7e\u540d\u65b9\u6cd5 post \u53ef\u4ee5\u6210\u529f\r<br />\u4f46\u662f\u5e26 body \u53c2\u6570\u7684 post \u6b7b\u6d3b\u8ba4\u8bc1\u5931\u8d25 ,\u6211\u662f\u4e0d\u662f\u9057\u6f0f\u4e86\u4ec0\u4e48\u4e1c\u897f \u6216\u8005\u4ec0\u4e48\u4e1c\u897f\u6ca1\u8003\u8651\u5230"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/xudzhang", 
        "name": "xudzhang", 
        "avatar": "https://cdn.v2ex.com/avatar/2eb0/413c/207675_large.png?m=1762653633"
      }, 
      "url": "https://www.v2ex.com/t/374959", 
      "title": "Ruby on Rails \u7684\u5de5\u7a0b\u600e\u4e48\u505a heap dump\uff1f", 
      "id": "https://www.v2ex.com/t/374959", 
      "date_published": "2017-07-13T01:28:09+00:00", 
      "content_html": "<p>\u6700\u8fd1\u8d77\u4e86 sidekiq \u540e\uff0c\u8fdb\u7a0b\u7684\u5185\u5b58\u6301\u7eed\u98d9\u5347\u2026\u2026</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/liteyou", 
        "name": "liteyou", 
        "avatar": "https://cdn.v2ex.com/avatar/757d/accd/220124_large.png?m=1490495679"
      }, 
      "url": "https://www.v2ex.com/t/370022", 
      "title": "\u4e3a\u4ec0\u4e48\u662f Ruby on Rails\uff1f\u800c\u4e0d\u662f Rails on Ruby\uff1f", 
      "id": "https://www.v2ex.com/t/370022", 
      "date_published": "2017-06-21T04:15:24+00:00", 
      "content_html": "RoR \u6ca1\u641e\u6e05\u695a\u987a\u5e8f\uff0c\u95ee\u522b\u4eba\u95ee\u9898\u5173\u4e8e RoR \u7684\u4e00\u4e9b\u7279\u6027\uff0c\u611f\u89c9 Rails on Ruby \u597d\u50cf\u66f4\u5408\u9002\uff1f Rails \u662f\u6846\u67b6\uff0cRuby \u662f\u8bed\u8a00\uff0c\u6846\u67b6\u57fa\u4e8e\uff08 base on \uff09\u8bed\u8a00\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u8bf4\u6210 Rails on Ruby \uff1f"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/WildCat", 
        "name": "WildCat", 
        "avatar": "https://cdn.v2ex.com/avatar/baf2/9ae7/39784_large.png?m=1710948175"
      }, 
      "url": "https://www.v2ex.com/t/369715", 
      "title": "Turbolinks \u4f1a\u5bfc\u81f4\u5fae\u4fe1\u7f51\u9875\u5728 iOS \u4e0a\u70b9\u51fb\u94fe\u63a5\u65f6\u51fa\u73b0 invalid signature \u9519\u8bef\uff0c Android \u548c\u5f00\u53d1\u8005\u5de5\u5177\u5219\u6b63\u5e38", 
      "id": "https://www.v2ex.com/t/369715", 
      "date_published": "2017-06-20T01:39:34+00:00", 
      "content_html": "<p>\u6700\u8fd1\u5728\u505a\u5fae\u4fe1\u7f51\u9875\u5f00\u53d1\uff0c\u7528\u7684\u662f <code>wechat</code> \u8fd9\u4e2a gem\u3002iOS \u4e0a\uff0c\u76ee\u524d\u751f\u6210\u7684\u7f51\u9875\uff0c\u9996\u9875\u6ca1\u95ee\u9898\uff0c\u4e00\u65e6\u70b9\u51fb\u4e00\u6b21\u94fe\u63a5\u5c31\u4f1a\u51fa\u73b0 invalid signature \u9519\u8bef\u3002</p>\n<p>\u641c\u7d22\u4e86\u5f88\u591a\u76f8\u5173\u5173\u952e\u8bcd\uff0c\u751a\u81f3\u5173\u4e8e React \u7684\u5fae\u4fe1\u7f51\u9875\u5f00\u53d1\u7684\u3002\u90fd\u6ca1\u627e\u5230\u4ec0\u4e48\u53ef\u4ee5\u5229\u7528\u7684\u8d44\u6599\u3002 \u5f88\u60f3\u7528 <code>turbolinks</code>\uff0c\u4f46\u662f\u73b0\u5728\u770b\u6765\u53ea\u80fd\u5173\u95ed\u4e86\u3002\u5947\u602a\u7684\u662f\u4e3a\u4ec0\u4e48 Android \u6b63\u5e38 iOS \u4e0d\u6b63\u5e38\uff0c\u6309\u7406\u8bf4 iOS \u7684\u6d4f\u89c8\u5668\u5e94\u8be5\u66f4\u7a33\u5b9a\u624d\u5bf9\u3002</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/fengjianzhi", 
        "name": "fengjianzhi", 
        "avatar": "https://cdn.v2ex.com/gravatar/6db12190f91845fd51cc14f246b1b12d?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/360011", 
      "title": "ruby on rails \u5982\u4f55\u4e0a\u4f20 swf \u6587\u4ef6", 
      "id": "https://www.v2ex.com/t/360011", 
      "date_published": "2017-05-09T00:45:43+00:00", 
      "content_html": "<p>\u60f3\u505a\u4e2a\u52a8\u56fe\u7f51\u7ad9\uff0cgif \u683c\u5f0f\u7684\u6587\u4ef6\u592a\u5927\uff0cswf \u66f4\u7701\u7a7a\u95f4\uff0c\u8bf7\u95ee\u7528\u4ec0\u4e48 gem \u4e0a\u4f20</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/wadezhao", 
        "name": "wadezhao", 
        "avatar": "https://cdn.v2ex.com/avatar/3c56/fe2f/11825_large.png?m=1410952541"
      }, 
      "url": "https://www.v2ex.com/t/326236", 
      "title": "\u7403\u5199\u4e00\u6bb5\u53ca\u5176\u7b80\u5355\u7684 Ruby \u4ee3\u7801", 
      "id": "https://www.v2ex.com/t/326236", 
      "date_published": "2016-12-08T09:20:29+00:00", 
      "content_html": "<p>\u7528 Redmine \u7ba1\u7406\u9879\u76ee\uff0c\u662f Ruby \u5199\u7684\uff0c Ruby \u8c8c\u4f3c\u5728 Windows \u4e0b\u5904\u7406\u4e2d\u6587\u7f16\u7801\u6709\u70b9\u95ee\u9898\uff0c\u5bfc\u81f4 Redmine \u4e2d\u4e00\u4e9b\u4e2d\u6587\u6587\u4ef6\u540d\u7684\u56fe\u7247\u663e\u793a\u4e0d\u6b63\u5e38\uff0c\u6211\u627e\u5230\u89e3\u51b3\u65b9\u6cd5\u4f46\u662f\u4e0d\u61c2 Ruby \uff0c\u8bf7\u6c42\u5e2e\u5fd9\u3002</p>\n<p>\u9700\u6c42\u5f88\u7b80\u5355\uff0c\u4e0b\u9762\u8fd9\u4e2a\u51fd\u6570\u662f\u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u5904\u7406\uff0c\u5904\u7406\u540e\u7684\u5b57\u7b26\u4e32\u5dee\u4e0d\u591a\u662f\u8fd9\u6837\uff1a\n/attachments/download/455/02%E5%AE.jpg\n\u6211\u60f3\u628a\u6700\u540e\u4e00\u4e2a\u201c/\u201d\u540e\u9762\u7684\u5b57\u7b26\u5220\u9664\uff0c\u5c31\u662f\u8fd4\u56de\u662f\n/attachments/download/455/\n\u5e94\u8be5\u5f88\u7b80\u5355\u5427\uff0c\u51fd\u6570\u5982\u4e0b\uff1a</p>\n<pre><code>def htmlesc( str, mode=:Quotes )\n  if str\n    str.gsub!( '&amp;', '&amp;amp;' )\n    str.gsub!( '\"', '&amp;quot;' ) if mode != :NoQuotes\n    str.gsub!( \"'\", '&amp;#039;' ) if mode == :Quotes\n    str.gsub!( '&lt;', '&amp;lt;')\n    str.gsub!( '&gt;', '&amp;gt;')\n  end\n  str\nend\n</code></pre>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/larkifly", 
        "name": "larkifly", 
        "avatar": "https://cdn.v2ex.com/avatar/112c/3ef9/29721_large.png?m=1361782469"
      }, 
      "url": "https://www.v2ex.com/t/324148", 
      "title": "\u521d\u5b66\u8005\u8bf7\u6559\u4e00\u4e2a ruby \u4f7f\u7528 leveldb \u7684\u95ee\u9898", 
      "id": "https://www.v2ex.com/t/324148", 
      "date_published": "2016-11-29T09:15:47+00:00", 
      "content_html": "\u80cc\u666f\u662f\uff1a\u6211\u76ee\u524d\u63a5\u624b\u522b\u4eba\u7684\u4ee3\u7801\r<br />\u95ee\u9898\uff1a\u5f53\u6211\u5728\u6587\u4ef6\u52a0\u4e0a require &quot;leveldb&quot; \u5c31\u5f00\u59cb\u62a5\u9519\uff1a\r<br />\r<br />.rvm/gems/ruby-2.3.0/gems/mongo-2.2.4/lib/mongo/protocol/message.rb:97:in `serialize': uninitialized constant BSON::ByteBuffer (NameError)\r<br />\r<br />\u5f53\u6211\u53bb\u6389 require &quot;leveldb&quot;\uff0c\u5c31\u6b63\u5e38\u4e86\u3002\r<br />\u8bf7\u95ee\u8fd9\u4e2a\u95ee\u9898\u600e\u4e48\u4fee\u590d\u4e86\uff1f\r<br />\r<br />ps \uff1a\u6211\u5df2\u7ecf\u5c1d\u8bd5\u5728 Gemfile \u91cc\u52a0 gem bson \uff0c\u6ca1\u6709\u7528"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/starvedcat", 
        "name": "starvedcat", 
        "avatar": "https://cdn.v2ex.com/avatar/e871/fced/191851_large.png?m=1475164568"
      }, 
      "url": "https://www.v2ex.com/t/322531", 
      "title": "Rails \u672c\u5730\u5f00\u53d1\uff0c\u8bbf\u95ee\u7f51\u7ad9\u5de8\u6162\uff0c\u4f60\u4eec\u90fd\u662f\u600e\u4e48\u89e3\u51b3\u7684\uff1f", 
      "id": "https://www.v2ex.com/t/322531", 
      "date_published": "2016-11-22T20:33:16+00:00", 
      "content_html": "<ol>\n<li>\u70b9\u4e00\u4e2a\u94fe\u63a5\uff0c\u8981\u7b49 20 \u79d2\u5de6\u53f3\u624d\u6253\u5f00\u3002\u3002\u3002\u3002</li>\n<li>\u73a9\u5177 APP \u4e5f\u5de8\u6162\uff0c\u4e0d\u662f\u4ee3\u7801\u95ee\u9898</li>\n<li>\u672c\u5730\u5f00\u53d1 Java PHP \u7f51\u9875\u90fd\u662f\u79d2\u5f00\uff0c\u4e0d\u662f\u6027\u80fd\u95ee\u9898</li>\n<li>\u90e8\u7f72\u5230\u8fdc\u7a0b\uff08 Heroku \uff09\uff0c\u70b9\u94fe\u63a5\u90fd\u662f\u79d2\u5f00\n\u5df2\u7ecf\u5c1d\u8bd5\u4e86\u7f51\u4e0a\u8bf4\u7684\u4e00\u4e9b\u65b9\u6cd5\uff0c\u6bd4\u5982\u6539 config\\environments\\development.rb \uff0c\u628a cache \u90fd\u6253\u5f00\u3002\u7136\u800c\u5e76\u6ca1\u6709\u663e\u8457\u7684\u6539\u5584\uff01\uff01</li>\n</ol>\n<p>\u6c42\u52a9\u4e86</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/starvedcat", 
        "name": "starvedcat", 
        "avatar": "https://cdn.v2ex.com/avatar/e871/fced/191851_large.png?m=1475164568"
      }, 
      "url": "https://www.v2ex.com/t/321968", 
      "date_modified": "2016-11-20T23:15:37+00:00", 
      "content_html": "<p>\u6211\u73b0\u5728\u6709</p>\n<pre><code>resources :books\n</code></pre>\n<p>\u73b0\u5728\u6211\u60f3\u8981\u8bbe\u8ba1 API \uff0c\u663e\u793a\u540c\u4e00\u4e2a\u4f5c\u8005\u5199\u7684\u6240\u6709\u4e66</p>\n<p>\u5047\u8bbe\uff0c ID \u4e3a 1 \u7684\u4e66\uff0c\u4f5c\u8005\u662f A \uff0c\u8fd9\u672c\u4e66\u7684 URI \u662f</p>\n<pre><code>/books/1\n</code></pre>\n<p>\u90a3\u4e48\u8fd9\u4e2a\u201c A \u5199\u7684\u6240\u6709\u4e66\u201d\u7684 URI \u5e94\u8be5\u600e\u4e48\u8bbe\u8ba1\u5462\uff1f</p>\n<p>\u8fd9\u4e2a\u201c\u4f5c\u8005\u201d\u5c31\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u4e0d\u662f\u4e00\u4e2a model</p>\n<p>\u662f\u4e0d\u662f\u8fd9\u6837\uff1a\uff08\u7528 similar \u8868\u793a\u540c\u4e00\u4e2a\u4f5c\u8005\uff09</p>\n<pre><code>/books/1/similar\n</code></pre>\n<p>\u4f46\u662f\u8fd9\u6837\u7684\u8bdd\uff0c\u53c8\u6ca1\u6709\u4f53\u73b0\u51fa A \u7684\u540d\u5b57</p>\n", 
      "date_published": "2016-11-20T23:15:18+00:00", 
      "title": "RESTful API \u8bbe\u8ba1\u95ee\u9898\uff08\u5f88\u57fa\u7840\uff09", 
      "id": "https://www.v2ex.com/t/321968"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/starvedcat", 
        "name": "starvedcat", 
        "avatar": "https://cdn.v2ex.com/avatar/e871/fced/191851_large.png?m=1475164568"
      }, 
      "url": "https://www.v2ex.com/t/321967", 
      "date_modified": "2016-11-20T20:43:48+00:00", 
      "content_html": "<p>\u6211\u73b0\u5728\u60f3\u7ed9\u4e00\u4e2a\u7c7b\u6dfb\u52a0\u4e00\u4e2a\u5b57\u7b26\u4e32\u7c7b\u53d8\u91cf\uff0c\u4f46 RubyMine \u63d0\u793a\u6211\u8bf4\u4e0d\u8981\u7528 class variable</p>\n<p>\u90a3\u5e94\u8be5\u7528\u4ec0\u4e48\u65b9\u6cd5\u5b9e\u73b0\u8fd9\u4e2a\u76ee\u7684\u5462\uff1f</p>\n", 
      "date_published": "2016-11-20T20:43:17+00:00", 
      "title": "ruby \u4e2d\u4f7f\u7528\u7c7b\u53d8\u91cf\u662f bad code style \u5417\uff1f\u6709\u6ca1\u6709\u66ff\u4ee3\u54c1\uff1f", 
      "id": "https://www.v2ex.com/t/321967"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/louzhumuyou", 
        "name": "louzhumuyou", 
        "avatar": "https://cdn.v2ex.com/avatar/a550/1d50/160937_large.png?m=1495497682"
      }, 
      "url": "https://www.v2ex.com/t/315170", 
      "date_modified": "2016-10-24T15:52:41+00:00", 
      "content_html": "<p>\u914d\u7f6e\u7684 jenkins \u662f master \u548c slave \u7684\u5f62\u5f0f\uff0c slave \u662f\u4e00\u53f0 mac mini,\u95ee\u9898\u7684\u5f15\u8d77\u662f\u56e0\u4e3a\u6267\u884c\u4e86</p>\n<pre><code>sudo remove ruby 2.2.0\nrvm use system\n</code></pre>\n<p>\u7136\u540e\u5c31\u51fa\u73b0\u7684\u73b0\u8c61\u5c31\u662f jenkins \u4e0a\u6253\u5370 ruby -v \u7684\u7248\u672c\u662f 2.2.0 \uff0c\u672c\u5730 slave \u4e0a\u6267\u884c ruby -v \u7684\u7248\u672c\u662f 2.3.1 \uff0c\n\u4f46\u662f\u540c\u6837\u6267\u884c rvm list \u90fd\u662f ruby 2.3.1 \uff0c\njenkins \u4e0a\u548c slave \u4e0a\u6253\u5370\u7684 ruby \u7248\u672c\u4e0d\u4e00\u81f4\uff0c\u5bfc\u81f4\u5f88\u591a\u57fa\u4e8e ruby \u5b89\u88c5\u7684\u547d\u4ee4\u4e0d\u80fd\u7528\u3002\n\u6c42\u61c2\u884c\u7684\u6307\u6559\uff0c\u95ee\u9898\u8be5\u5982\u4f55\u89e3\u51b3\uff0c\u6211\u5e0c\u671b\u662f jenkins \u4e0a\u6267\u884c ruby -v \u7684\u7248\u672c\u8ddf slave mac \u4e0a\u547d\u4ee4\u884c\u6267\u884c\u7684\u7ed3\u679c\u5e94\u8be5\u662f\u4e00\u81f4\u3002\n\u80fd\u60f3\u5230\u7684\u662fjenkins\u662f\u7528\u57fa\u4e8essh\u547d\u4ee4\u7684\u65b9\u5f0f\u767b\u5f55\u7684\uff0c\u672c\u5730\u547d\u4ee4\u884c\u76f4\u63a5\u6253\u5f00\uff0c\u6240\u4ee5\u767b\u5f55\u65b9\u5f0f\u662f\u4e0d\u4e00\u81f4\u7684?</p>\n", 
      "date_published": "2016-10-24T15:51:02+00:00", 
      "title": "jenkins \u6267\u884c ruby -v \u548c\u5728 slave \u4e0a\u6267\u884c ruby -v \u7248\u672c\u4e0d\u4e00\u81f4", 
      "id": "https://www.v2ex.com/t/315170"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/jiangbianwanghai", 
        "name": "jiangbianwanghai", 
        "avatar": "https://cdn.v2ex.com/gravatar/d461df81a9f0dd1922319f24990e3ca3?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/315003", 
      "title": "Tower,Worktile,Teambition \u5728\u4f4e\u5c42\u5b58\u50a8\u4e0a\u7684\u5dee\u522b\u662f\u4ec0\u4e48\uff1f", 
      "id": "https://www.v2ex.com/t/315003", 
      "date_published": "2016-10-24T05:42:05+00:00", 
      "content_html": "<p>\u5b83\u4eec\u4e09\u4e2a\u90fd\u662f\u57fa\u4e8e Pyhton \u6216 Ruby \u5f00\u53d1\u7684\u5417\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 Php?\n\u5728\u4f4e\u5c42\u5b58\u50a8\u4e0a\u4ed6\u4eec\u662f\u7528\u7684\u4ec0\u4e48\uff1f\u662f\u5426\u91c7\u53d6\u4e86\u7b2c\u4e09\u65b9\u7684\u4e91\u89e3\u51b3\u65b9\u6848\u5462\uff1f</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/Byronlee", 
        "name": "Byronlee", 
        "avatar": "https://cdn.v2ex.com/avatar/1bd7/d4ea/43041_large.png?m=1701950122"
      }, 
      "url": "https://www.v2ex.com/t/313217", 
      "title": "\u826f\u5fc3\u4e4b\u4f5c\uff0c\u5168\u7ad9\u5de5\u7a0b\u5e08\u7684\u72ec\u767d [\u89c6\u9891]", 
      "id": "https://www.v2ex.com/t/313217", 
      "date_published": "2016-10-16T18:03:34+00:00", 
      "content_html": "<p>\u4e00\u4e2a\u5168\u7ad9\u5de5\u7a0b\u5e08\uff0c\u5e94\u8be5\u6709\u54ea\u4e9b\u6b63\u786e\u7684\u6280\u672f\u8def\u7ebf?\n\u5e94\u8be5\u6709\u54ea\u4e9b\u6b63\u786e\u7684\u59ff\u52bf\uff1f<br>\n\u5e94\u8be5\u5982\u4f55\u9009\u62e9\u81ea\u5df1\u7684\u9053\u7406\uff1f</p>\n<p>\u7b54\u6848\u5728\u6bcf\u4e2a\u4eba\u7684\u5fc3\u4e2d</p>\n<h3>\u5e94\u8be5\u8fdb\u5165\u89d2\u8272</h3>\n<p>\u5728\u8fd9\u4e2a\u5145\u6ee1\u96fe\u973e\u7684\u591c\u665a\n\u5750\u5728\u5c4b\u91cc\u5c0f\u5c0f\u7684\u4e66\u684c\u65c1\n\u56de\u60f3\u7740\u4e00\u5207\n\u4ece\u5f53\u521d\u51b3\u5b9a\u505a\u8fd9\u4ef6\u4e8b, \u5230\u8c03\u7814\uff0c\u5230\u4ea7\u54c1\uff0c\u5230\u8bbe\u8ba1\uff0c\u5230\u5f00\u53d1\uff0c\u5230\u4e0a\u7ebf\uff0c\u8fd9\u4e00\u5207\u771f\u6240\u8c13\u9971\u7ecf\u98ce\u971c\n\u5728\u8fd9\u4e2a\u5185\u5bb9\u6cdb\u6ee5\u7684\u5e74\u4ee3\uff0c\u4ec0\u4e48\u6837\u7684\u5185\u5bb9\u4ea7\u54c1\u624d\u9002\u5408\u6211\u4eec? \u8981\u89e3\u51b3\u4e00\u4e2a\u4ec0\u4e48\u6837\u7684\u95ee\u9898? \u5982\u4f55\u89e3\u51b3\uff1f \u8fd9\u662f\u6211\u8fd9\u534a\u5e74\u5185\u5fc3\u81ea\u95ee\u9891\u7387\u6700\u591a\u7684\u95ee\u9898</p>\n<p>\u4eca\u5929\u5b83\u7ec8\u4e8e\u6709\u4e86\u4e00\u4e2a\u5b8c\u7f8e\u7684\u7b54\u6848</p>\n<h3>\u4ed6\u662f\u4ec0\u4e48</h3>\n<p>\u5b89\u9759\u5730\u8111\u8865 \u4e3b\u65e8\u4ece\u4e92\u8054\u7f51\u4fe1\u606f\u7ea2\u6d77\u4e2d\u6536\u5f55\u70ed\u70b9\uff0c\u7ecf\u5178\u7684\u89c6\u9891\u8d44\u6e90\u3002\u76ee\u6807\u7528\u6237\u4e3b\u8981\u9488\u5bf9\u4e92\u8054\u7f51\u4eba\u7fa4, \u89c6\u9891\u5185\u5bb9\u6db5\u76d6\u4eba\u4eec\u65f6\u5e38\u5173\u5fc3\u7684\u9886\u57df\uff0c\u4ed6\u4eec\u4e3b\u8981\u5305\u542b\uff1a\u7535\u5f71\u3001\u521b\u4e1a\u7ecf\u9a8c\u5206\u4eab\u3001\u878d\u8d44\u3001\u5927\u4f1a\u89c6\u9891\u3001\u7ebf\u4e0b\u6d3b\u52a8\u3001\u4e13\u4e1a\u6280\u80fd\u3001\u7f16\u7a0b\u3001\u77ed\u89c6\u9891\u3001\u70ed\u70b9\u3001\u79d1\u6280\u3001\u4f01\u4e1a\u54c1\u724c\u3001\u641e\u7b11\u3001\u6559\u80b2\u3001\u751f\u6d3b\u7b49\u3002 \u5b89\u9759\u7684\u8111\u8865\u540c\u65f6\u4e5f\u662f\u65b0\u4e00\u4ee3 CGC \u89c6\u9891\u5185\u5bb9\u5206\u53d1\u5e73\u53f0\uff0c\u8fd9\u91cc\u6536\u5f55\u4e86\u4e92\u8054\u7f51\u4eba\u5173\u6ce8\u7684\u6d77\u91cf\u89c6\u9891\uff0c\u91c7\u7528\u9886\u5148\u7684\u6570\u636e\u5206\u6790\u6280\u672f\uff0c \u771f\u6b63\u7684\u505a\u5230\uff1a\u4e16\u754c\u7684\u7cbe\u5f69\uff0c\u5b89\u9759\u5730\u8111\u8865\u3002</p>\n<h3>\u5e94\u8be5\u6765\u70b9\u5e72\u8d27,  \u8ba9\u6211\u4eec\u901a\u8fc7\u4e00\u4e2a\u77ed\u7247\uff0c\u4e00\u8d77\u9886\u7565\u4e00\u4e0b\u5427 [\u9057\u61be\u8fd9\u91cc\u4e0d\u80fd\u6b63\u786e\u63d2\u5165\u89c6\u9891]</h3>\n<p>\u5b98\u7f51\u94fe\u63a5\uff1a <a href=\"http://anjingdenaobu.com?utm_source=ruby-china\" rel=\"nofollow\">http://anjingdenaobu.com?utm_source=ruby-china</a></p>\n<p>\u64ad\u653e\u94fe\u63a5 1 \uff1a <a href=\"http://v.qq.com/x/page/h0336p7uc1k.html\" rel=\"nofollow\">http://v.qq.com/x/page/h0336p7uc1k.html</a></p>\n<p>\u64ad\u653e\u94fe\u63a5 2 \uff1a <a href=\"http://anjingdenaobu.com/p/5006870.html?utm_source=next_comment\" rel=\"nofollow\">http://anjingdenaobu.com/p/5006870.html?utm_source=next_comment</a></p>\n<h3>\u52a0\u5165\u8ba8\u8bba</h3>\n<p><img alt=\"\u4ea4\u6d41\u7fa4\" src=\"http://p1.bqimg.com/567571/2fa75b5c996f61ff.png\"></p>\n<p>\u6b22\u8fce\u5404\u4f4d\u5c0f\u4f19\u4f34\u6765\u5410\u69fd \u6216\u8005\u4ea4\u6d41</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/venson", 
        "name": "venson", 
        "avatar": "https://cdn.v2ex.com/avatar/1e48/c442/1010_large.png?m=1475652759"
      }, 
      "url": "https://www.v2ex.com/t/311636", 
      "title": "\u6709\u6ca1\u6709\u4eba\u7528\u4e2a\u4eba\u7535\u8111+\u82b1\u751f\u58f3+RoR\uff0c\u5728\u5bb6\u642d\u5efa\u4e00\u4e2a\u81ea\u5df1\u7684\u670d\u52a1\u5668\uff1f", 
      "id": "https://www.v2ex.com/t/311636", 
      "date_published": "2016-10-10T07:36:10+00:00", 
      "content_html": "\u82b1\u751f\u58f3\u6216\u7c7b\u4f3c\u7684\u8f6f\u4ef6"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/XuanYuan", 
        "name": "XuanYuan", 
        "avatar": "https://cdn.v2ex.com/avatar/2539/7b4a/16479_large.png?m=1762843509"
      }, 
      "url": "https://www.v2ex.com/t/302280", 
      "title": "\u4e4b\u524d\u5df2\u7ecf\u53ef\u4ee5\u5199\u4e00\u4e9b\u7b80\u5355\u7684\u4e1c\u897f\u4e86\uff0c\u73b0\u5728\u53d1\u73b0\u90fd\u5fd8\u5b8c\u4e86\uff0c\u6709\u6ca1\u6709\u7c7b\u4f3c\u7ecf\u5386\u7684\u540c\u5b66\uff1f\u600e\u4e48\u7834\uff1f", 
      "id": "https://www.v2ex.com/t/302280", 
      "date_published": "2016-08-28T08:51:06+00:00", 
      "content_html": ""
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/livedutvchina", 
        "name": "livedutvchina", 
        "avatar": "https://cdn.v2ex.com/gravatar/dfb391929e4e68df8c44796699685cc4?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/290513", 
      "title": "\u89c6\u9891\u63a8\u8350\uff1a\u4f7f\u7528 Rails 5 \u5f00\u53d1\u4e00\u6b3e Ruby on Rails app", 
      "id": "https://www.v2ex.com/t/290513", 
      "date_published": "2016-07-05T14:19:47+00:00", 
      "content_html": "<p>\u4e00\u4e2a\u6cd5\u56fd\u7684\u7a0b\u5e8f\u5458\u6b63\u5728\u5f00\u53d1\u8fd9\u6b3e APP \u3002\u636e\u4ecb\u7ecd\uff0c\u8fd9\u4e2a APP \u7528\u4f5c\u652f\u6301\u5546\u4e1a\u4f1a\u5458\u5361\u7684\u7ba1\u7406\u7cfb\u7edf\u3002\u4f1a\u5458\u53ef\u4ee5\u67e5\u8be2\u4ed6\u4eec\u7684\u8d26\u53f7\u4ee5\u53ca\u5404\u79cd\u4f18\u60e0\u4fe1\u606f\u3002</p>\n<p><a href=\"https://www.livecoding.tv/aeradriel/videos/4Oo5J-ruby-on-rails-app-using-rails-5-7\" rel=\"nofollow\">https://www.livecoding.tv/aeradriel/videos/4Oo5J-ruby-on-rails-app-using-rails-5-7</a></p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/Andor_Chen", 
        "name": "Andor_Chen", 
        "avatar": "https://cdn.v2ex.com/avatar/0402/5959/339_large.png?m=1680834107"
      }, 
      "url": "https://www.v2ex.com/t/289837", 
      "title": "Ruby on Rails \u6559\u7a0b\uff08\u539f\u4e66\u7b2c 4 \u7248\uff09\u53d1\u5e03", 
      "id": "https://www.v2ex.com/t/289837", 
      "date_published": "2016-07-02T10:34:50+00:00", 
      "content_html": "<p><img alt=\"\" src=\"https://ruby-china-files.b0.upaiyun.com/photo/2016/69c1075b2e3f33c7e504627994c84fab.jpg\"></p>\n<p>Rails 5 \u53d1\u5e03\u4e86\uff0c\u53d1\u73b0 V \u7ad9\u6709\u51e0\u8d34\u5728\u8ba8\u8bba\u76f8\u5173\u8bdd\u9898\uff0c\u6211\u4e5f\u51d1\u4e2a\u70ed\u95f9\u3002</p>\n<p>\u7ecf\u8fc7\u4e00\u4e2a\u591a\u6708\u7684\u4fee\u8ba2\uff0c<strong>\u300a Ruby on Rails \u6559\u7a0b\uff08\u539f\u4e66\u7b2c 4 \u7248\uff09\u300b\u6b63\u5f0f\u53d1\u5e03\u4e86</strong>\u3002</p>\n<p>\u7b2c 4 \u7248\u4e0e\u7b2c 3 \u7248\u7684\u4e3b\u8981\u53d8\u5316\u6709\uff1a</p>\n<ul>\n<li>Rails \u7248\u672c\u7531 4.2 \u5347\u7ea7\u5230 5 \uff1b</li>\n<li><code>rake</code> \u547d\u4ee4\u5168\u90e8\u7edf\u4e00\u4e3a <code>rails</code> \u547d\u4ee4\uff1b</li>\n<li>12 \u7ae0\u53d8\u6210\u4e86 14 \u7ae0\uff08\u628a\u8f83\u957f\u7684\u4e24\u7ae0\u5206\u62c6\u4e86\uff09\uff1b</li>\n<li>\u589e\u52a0\u4e86\u5927\u91cf\u7ec3\u4e60\uff0c\u800c\u4e14\u653e\u5728\u5404\u5c0f\u8282\u5185\uff1b</li>\n</ul>\n<p>\u7b2c 4 \u7248\u7684\u7535\u5b50\u4e66\u5df2\u7ecf\u5f00\u59cb\u9500\u552e\uff0c\u4e0a\u7ebf\u9996\u5468<strong>\u516b\u6298</strong>\u4f18\u60e0\uff0c\u8bf7\u70b9\u51fb\u4e0b\u8ff0\u4e24\u4e2a\u94fe\u63a5\u4e2d\u7684\u4e00\u4e2a\u8d2d\u4e70\uff1a</p>\n<ul>\n<li><a href=\"https://selfstore.io/products/189?coupon=4thLaunchWeek\" rel=\"nofollow\">https://selfstore.io/products/189?coupon=4thLaunchWeek</a> \uff08\u652f\u4ed8\u5b9d\uff09</li>\n<li><a href=\"https://leanpub.com/rails-tutorial-cn/c/4thLaunchWeek\" rel=\"nofollow\">https://leanpub.com/rails-tutorial-cn/c/4thLaunchWeek</a> \uff08 PayPal/\u4fe1\u7528\u5361\uff09</li>\n</ul>\n<p>\u82f1\u6587\u7248\u9700\u8981\u91cd\u65b0\u8d2d\u4e70\uff0c\u4f46\u662f\u6211\u51b3\u5b9a\uff1a\u7b2c 3 \u7248\u7684\u8001\u8bfb\u8005\u53ef\u4ee5\u514d\u8d39\u5347\u7ea7\u5230\u7b2c 4 \u7248\u3002\u5982\u679c\u4f60\u4e4b\u524d\u8d2d\u4e70\u8fc7\u7b2c 3 \u7248\uff0c\u8bf7\u67e5\u6536\u90ae\u4ef6\uff0c\u91cc\u9762\u6709\u7b2c 4 \u7248\u7684\u4e0b\u8f7d\u94fe\u63a5\u3002</p>\n<p>\u8fd9\u662f\u6211\u5f00\u59cb\u7ffb\u8bd1\u300a Ruby on Rails \u6559\u7a0b\u300b\u4ee5\u6765\u7684\u7b2c\u56db\u4e2a\u7248\u672c\uff08\u4e4b\u524d\u51e0\u7248\u90fd\u53ef\u4ee5<a href=\"http://railstutorial-china.org/book/\" rel=\"nofollow\">\u514d\u8d39\u5728\u7ebf\u9605\u8bfb</a>\uff09\uff0c\u5728\u6b64\u8fc7\u7a0b\u4e2d\u5f97\u5230\u4e86\u4f17\u591a\u8bfb\u8005\u7684\u5927\u529b\u652f\u6301\uff0c\u518d\u6b21\u611f\u8c22\u4f60\u4eec\uff01</p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/livedutvchina", 
        "name": "livedutvchina", 
        "avatar": "https://cdn.v2ex.com/gravatar/dfb391929e4e68df8c44796699685cc4?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/289804", 
      "title": "\u4e00\u4e2a\u7f8e\u5973\u7a0b\u5e8f\u5458\u5f00\u53d1\u7684 Rails App", 
      "id": "https://www.v2ex.com/t/289804", 
      "date_published": "2016-07-02T07:15:21+00:00", 
      "content_html": "<p>\u8fd9\u4e2a\u8f6f\u4ef6\u662f\u7531\u4e00\u4e2a\u7f8e\u5973\u5f00\u53d1\u7684\uff0c\u662f\u4e00\u4e2a\u7528\u6765\u7ba1\u7406\u5b66\u751f\u7684 APP \u3002\u89c6\u9891\u5df2\u7ecf\u8d85\u8fc7 16000 \u6b21\u70b9\u51fb\u4e86\u3002\u5973\u751f\u7f16\u7a0b\u4e0d\u6bd4\u7537\u751f\u900a\u8272\u3002</p>\n<p>Building a Rails app for managing students\n<a href=\"https://www.livecoding.tv/pinklily/videos/ZDMQK-building-a-rails-app-for-managing-students-2\" rel=\"nofollow\">https://www.livecoding.tv/pinklily/videos/ZDMQK-building-a-rails-app-for-managing-students-2</a></p>\n"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/lianghudou", 
        "name": "lianghudou", 
        "avatar": "https://cdn.v2ex.com/gravatar/2e429d8cd7c6eb8a1a52391a61dbc558?s=73&d=retro"
      }, 
      "url": "https://www.v2ex.com/t/289785", 
      "date_modified": "2016-09-02T22:23:17+00:00", 
      "content_html": "\u57fa\u672c\u4e0a 3 \u5e74\u4ee5\u540e\uff0c\u6362\u670d\u52a1\u5668\u7684\u65f6\u5019\u9879\u76ee\u5c31\u7b49\u4e8e\u76fc\u4e86\u6b7b\u5211\u3002\r<br />\r<br />\u6211 13 \u5e74\u505a\u4e86\u4e2a\u9879\u76ee\uff0c\u7528\u7684\u5f53\u65f6\u6700\u65b0\u7684 rails3.2 \u3002\u73b0\u5728\u8f6c\u670d\u52a1\u5668\uff0c\u4e0d\u77e5\u9053\u90a3\u4e2a gem \u4f9d\u8d56\u4e86 eventmachine \uff0c\u5e76\u4e14\u5fc5\u987b\u662f 1.0.0 \u7248\u7684\uff0c\u4e3a\u4e86\u517c\u5bb9\u8fd9\u4e2a 1.0.0 \u7248\uff0c\u4e0d\u5f97\u4e0d\u7528 ruby 2.0.0 \uff0c\u4f46\u662f\uff0c\u5728\u8fd9\u4e2a\u4f4e\u7248\u672c\u7684 ruby \u4e0a\uff0c rake \u5df2\u7ecf\u7f62\u5de5\u4e86\uff0c\u5fc5\u987b\u5f97 2.2.2 \u4ee5\u4e0a\u3002\r<br />\r<br />\u5176\u5b9e\u6211\u7528\u7684 gem \u4e0d\u7b97\u591a\uff0c Gemfile \u91cc\u6ee1\u6253\u6ee1\u7b97\u4e5f\u5c31 10 \u4e2a\u5de6\u53f3\u3002\r<br />\r<br />linux\u73af\u5883\u7684\u8de8\u5ea6\u4e5f\u4e0d\u7b97\u5927\uff0c\u4ec5\u4ec5\u4eceubuntu12\u5230ubuntu14\uff0c\u96be\u4ee5\u60f3\u8c61\u5230ubuntu18\u3001ubuntu20\uff0c\u8fd9\u4e2a\u9879\u76ee\u8fd8\u6709\u6ca1\u6709\u7ee7\u7eed\u8fd0\u884c\u7684\u53ef\u80fd\u3002\r<br />\r<br />\u5982\u679c\u4f60\u7684 web \u9879\u76ee\u6253\u7b97\u8ba9\u5b83\u7a33\u5b9a\u8fd0\u884c 10 \u5e74\u4ee5\u4e0a\uff0c java \u548c php \u4ecd\u662f\u6700\u4f73\u9009\u62e9\uff0c\u90a3\u4e9b\u65b0\u6280\u672f\u62ff\u6765\u73a9\u73a9\u5c31\u884c\u4e86\uff0c\u522b\u7528\u751f\u4ea7\u73af\u5883\u3002", 
      "date_published": "2016-07-02T04:26:09+00:00", 
      "title": "\u9700\u8981\u957f\u671f\u8fd0\u8425\u7684\u9879\u76ee\uff0c\u5343\u4e07\u522b\u7528 rails", 
      "id": "https://www.v2ex.com/t/289785"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/kyrre", 
        "name": "kyrre", 
        "avatar": "https://cdn.v2ex.com/avatar/7c97/d0f1/112124_large.png?m=1671153425"
      }, 
      "url": "https://www.v2ex.com/t/289583", 
      "date_modified": "2016-07-01T09:40:50+00:00", 
      "content_html": "\u7136\u800c HN \u4e0a\u5bf9\u6b64\u7684\u8bc4\u8bba\u90fd\u662f\u5728\u8ba8\u8bba Elixir \u548c Phoenix \uff0c\u6211\u4e5f\u662f\u9189\u4e86......\r<br />Ruby/Rails \u679c\u7136\u8fd8\u662f\u56e0\u4e3a\u6027\u80fd\u4e0d\u884c\u88ab\u5927\u4f19\u8fb9\u7f18\u5316\uff0c\u770b\u6765\u4e0d\u8f6c\u4e0d\u884c\u4e86......", 
      "date_published": "2016-07-01T05:29:12+00:00", 
      "title": "Rails \u51fa 5.0 \u4e86", 
      "id": "https://www.v2ex.com/t/289583"
    }, 
    {
      "author": {
        "url": "https://www.v2ex.com/member/TangMonk", 
        "name": "TangMonk", 
        "avatar": "https://cdn.v2ex.com/avatar/c5f1/ae9e/55793_large.png?m=1644466105"
      }, 
      "url": "https://www.v2ex.com/t/288754", 
      "title": "ruby \u5982\u4f55\u505a race conditions \u6d4b\u8bd5\uff1f", 
      "id": "https://www.v2ex.com/t/288754", 
      "date_published": "2016-06-28T01:38:48+00:00", 
      "content_html": ""
    }
  ]
}