<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>lukefan (Luke Fan)</title>
    <link>https://ruby-china.org/lukefan</link>
    <description/>
    <language>en-us</language>
    <item>
      <title>webpack 打包，怎么将体积降下来？</title>
      <description>&lt;p&gt;我的应用里面，使用了 react、apollo graphql、jQuery、bootstrap 等等一大堆的库，
没多少代码，webpacker:compile 出来的包，就 1.6M 了。
怎么调整，可以页面通过 cdn 调用各种库，只将自己的代码打包，并压缩到尽可能小呢？&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Sun, 07 Feb 2021 15:27:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/40899</link>
      <guid>https://ruby-china.org/topics/40899</guid>
    </item>
    <item>
      <title>通过 js 实现 &lt;a href="remote server url" download /&gt;的方法</title>
      <description>&lt;p&gt;以前写了一个美剧下载站的应用，遇到了一个尴尬的问题。
所有的 torrent 文件，都存放到了七牛云存储的 cdn 上，链接上去之后，每次点击，浏览器会在新窗口中将 torrent 作为文本文件直接打开。
后来发现，有一个 H5 的标记，可以写&lt;a href="url"&gt;&lt;/a&gt;，浏览器收到这种标签，就知道要用什么文件名来下载文件。
测试了几次，发现没有效果。
再仔细看了看文档，这里面有一个限制，url 必须是本站的地址，不能是站外的地址。于是在网上找了一下，最后发现了一种还算简单地处理方法。
用 fetch 直接将远端的 url 作为 blob 拉过来，然后通过 window.URL.createObjectURL 函数来生成一个临时的本地地址，再下载，然后注销掉临时本地地址。
代码如下，没有用 torrent，用了一张图片，点击直接下载而不是打开：&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://5b0988e595225.cdn.sohucs.com/images/20181229/39193e04345340818c0a5a0345f9d107.jpeg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;responseType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blob&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/jpeg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;download&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a.jpg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revokeObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Oops, error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;download&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <author>lukefan</author>
      <pubDate>Mon, 25 Jan 2021 18:19:32 +0800</pubDate>
      <link>https://ruby-china.org/topics/40858</link>
      <guid>https://ruby-china.org/topics/40858</guid>
    </item>
    <item>
      <title>graphql 的 mutation 参数搞不明白了</title>
      <description>&lt;p&gt;以前写过一些 graphql 的小练习，只用过 query，这是第一次用 mutation 去尝试更新数据。&lt;/p&gt;

&lt;p&gt;我使用的是 gem 'graphql', '~&amp;gt; 1.11.6' &lt;/p&gt;

&lt;p&gt;使用 rails g graphql:mutation Add_Person&lt;/p&gt;

&lt;p&gt;创建了相关文件，然后去修改 add_person.rb&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Mutations&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AddPerson&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseMutation&lt;/span&gt;
    &lt;span class="c1"&gt;# TODO: define return fields&lt;/span&gt;
    &lt;span class="c1"&gt;# field :post, Types::PostType, null: false&lt;/span&gt;
    &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:person&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PersonType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;

    &lt;span class="c1"&gt;# TODO: define arguments&lt;/span&gt;
    &lt;span class="c1"&gt;# argument :name, String, required: true&lt;/span&gt;
    &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;required: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;required: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="ss"&gt;:description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;required: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;description: &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;age: &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;description: &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="c1"&gt;# TODO: define resolve method&lt;/span&gt;
    &lt;span class="c1"&gt;# def resolve(name:)&lt;/span&gt;
    &lt;span class="c1"&gt;#   { post: ... }&lt;/span&gt;
    &lt;span class="c1"&gt;# end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;遇到的问题是：&lt;/p&gt;

&lt;p&gt;输入的参数，只有一个 AddPersonInput 类型的，叫做 input 的参数。我定义的 name、age、description 什么的都没有了。这是怎么个玩儿法？如果生写，就会报错，说是 input 定义了，但是没有填写。&lt;/p&gt;

&lt;p&gt;在网上查了一下，没有看到更多的东西了。&lt;/p&gt;

&lt;p&gt;另外，我看到网上的一些例子里面定义的 Type，都是继承自 Node，而我是用 rails g graphql:object 做的，所以都是继承自 object。不知道有什么差异。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Fri, 01 Jan 2021 19:20:45 +0800</pubDate>
      <link>https://ruby-china.org/topics/40772</link>
      <guid>https://ruby-china.org/topics/40772</guid>
    </item>
    <item>
      <title>mongoid、graphql 环境下，求推荐一种安全认证方式</title>
      <description>&lt;p&gt;业余程序员，想要做一个基于 mongoid 和 graphql 的服务端。
然后用 react 和 flutter 做 web 和移动的前端。
想要找一种认证方法，可以让用户登录，并只为认证用户提供服务。
有什么比较简单的方案吗？&lt;/p&gt;

&lt;p&gt;尝试了 graphql_devise，改到 mongoid 下，就各种错误。
graphql_auth，还没看明白。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Tue, 29 Dec 2020 19:52:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/40761</link>
      <guid>https://ruby-china.org/topics/40761</guid>
    </item>
    <item>
      <title>尝试使用 cancancan，数据是存在什么地方的啊？</title>
      <description>&lt;p&gt;尝试使用 cancancan
加入了：
gem 'cancancan'
gem 'cancancan-mongoid'
执行了：
bundle install
rails g cancan:ability&lt;/p&gt;

&lt;p&gt;然后呢？
user.admin？这个 admin 是存在什么地方的？包括哪些 role 信息是存在什么地方的？
是不是我少做了什么？&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Fri, 25 Dec 2020 17:07:47 +0800</pubDate>
      <link>https://ruby-china.org/topics/40747</link>
      <guid>https://ruby-china.org/topics/40747</guid>
    </item>
    <item>
      <title>稍微折腾了一下 FontAwesome</title>
      <description>&lt;p&gt;作为一个将编程作为业余爱好的老程序员，折腾一下前端技术，实在是比较痛苦的过程。
前几天尝试着将老版本的 ruby on rails 程序升级上来的过程中学习了一下 webpack 和 react。
然后就尝试着将 jquery 和 bootstrap 搞进去。于是参照了：&lt;a href="/syutran" class="user-mention" title="@syutran"&gt;&lt;i&gt;@&lt;/i&gt;syutran&lt;/a&gt; 的 &lt;a href="https://ruby-china.org/topics/38992" title=""&gt;新手问题 rails 6 boostrap 尝鲜&lt;/a&gt; 中的代码。
唯一差别的是，将 NavBar 的部分，搞到了一个 react 的组件中，这个过程中需要将所有的 class=替换成了 className=，将 tabindex 替换成了 tabIndex。没有问题。
后来发现里面有个问题，就是 fontawesome 的引用出错了，文档中也说了这个没搞明白，于是我就自己试验了一下。&lt;/p&gt;

&lt;p&gt;这种字体图标，一共尝试了三种方式：&lt;/p&gt;

&lt;p&gt;1、直接从 &lt;a href="https://fontawesome.com/" rel="nofollow" target="_blank" title=""&gt;FontAwesome 官网&lt;/a&gt;上注册，然后生成了一共 kit 的链接，在 app/views/layouts/application.html.erb 中做引用
可以直接通过&lt;i&gt;标记引用各种图标了
这种方式据说是最快的（有 cdn 在工作），不过好像免费方式的调用次数是有限制的，具体没看&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;2、通过&lt;a href="https://github.com/FortAwesome/font-awesome-sass" rel="nofollow" target="_blank" title=""&gt;font-awesome-sass&lt;/a&gt; 这个 gem 来实现。
先在 Gemfile 中添加&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'font-awesome-sass'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'~&amp;gt; 5.15.1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;做 bundle install
然后修改 app/assets/stylesheets/application.css
先将其改名为 application.css.scss
然后添加&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"font-awesome-sprockets"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="vi"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"font-awesome"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;i&gt;就可以工作了。
而且还可以通过 icon 这个函数，直接在 erb 文件中输出图标。&lt;/i&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= icon('fas', 'flag') %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不过这个方法有一个讨厌的地方，也是最后我舍弃了这种方式的主要原因。
我将代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"font-awesome-sprockets"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="vi"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"font-awesome"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加到了 app/javascript/styles/application.scss 中，然后再/app/javascript/packs/application.js 中引用 &lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/application&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会报错，font-awesome-sprockets 文件找不到，&lt;i&gt;也不工作。为了后面所有的前端代码都放在统一的地方 app/assets 里面不再添加代码，这种方式被舍弃了。&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;3、使用&lt;a href="https://github.com/FortAwesome/react-fontawesome" rel="nofollow" target="_blank" title=""&gt;react-fontawesome&lt;/a&gt;
首先先读&lt;a href="https://fontawesome.com/how-to-use/on-the-web/using-with/react" rel="nofollow" target="_blank" title=""&gt;官方文档&lt;/a&gt;
作为免费用户，先添加各种免费库&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;yarn&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="vi"&gt;@fortawesome&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fontawesome&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;svg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="vi"&gt;@fortawesome&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;solid&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;svg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;icons&lt;/span&gt; &lt;span class="vi"&gt;@fortawesome&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fontawesome&lt;/span&gt;
&lt;span class="n"&gt;yarn&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="vi"&gt;@fortawesome&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;brands&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;svg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;icons&lt;/span&gt; &lt;span class="vi"&gt;@fortawesome&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;regular&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;svg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;icons&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后就是在 React 中直接用组件来显示图标，这个过程中有一个比较麻烦的就是任何图标在调用之前，先要去做 import。&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fortawesome/react-fontawesome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;faCoffee&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fortawesome/free-solid-svg-icons&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;faCoffee&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;稍微简单一点儿的方法是，先引用一堆，并加入到一个库中，然后再在不同的组件中调用
注册：&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;library&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fortawesome/fontawesome-svg-core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fab&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fortawesome/free-brands-svg-icons&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;faCheckSquare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;faCoffee&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fortawesome/free-solid-svg-icons&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;library&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fab&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;faCheckSquare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;faCoffee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;调用：&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fortawesome/react-fontawesome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Beverage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;check-square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;coffee&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;hot&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;调用&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fortawesome/react-fontawesome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Showcase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fab&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fab&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;microsoft&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fab&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;google&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FontAwesomeIcon&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;check-square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;With&lt;/span&gt; &lt;span class="nx"&gt;Coffee&lt;/span&gt; &lt;span class="nx"&gt;Checked&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;these&lt;/span&gt; &lt;span class="nx"&gt;companies&lt;/span&gt; &lt;span class="nx"&gt;always&lt;/span&gt; &lt;span class="nx"&gt;know&lt;/span&gt; &lt;span class="nx"&gt;their&lt;/span&gt; &lt;span class="nx"&gt;coffee&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;hot&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;前面引用并加入到 library 中的 fab 是品牌图标库中的所有 fab 图标。引用一次之后，就都可以调用了。
这里面引用的格式我自己也有点儿晕，如果是直接 import 进来的图标，
比如 import { faCoffee } from '&lt;a href="/fortawesome" class="user-mention" title="@fortawesome"&gt;&lt;i&gt;@&lt;/i&gt;fortawesome&lt;/a&gt;/free-solid-svg-icons' ，那么调用的时候最好用 
如果是在 library 里面 add 过的，直接用 也是可以的。
如果是一次引入了一堆的那种情况，则需要用来调用。&lt;/p&gt;

&lt;p&gt;这里面还有一个问题，加载了这种方式之后，&lt;i&gt;是不工作的。
需要再加上一段代码：&lt;/i&gt;&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;dom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fortawesome/fontawesome-svg-core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;才可以让&lt;i&gt;工作起来。不过我没太搞清楚这个代码的作用域是什么样的。并不是每次都灵。&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;最终，因为想要用新的 rails6。各种前端的东西，准备交给 react 来搞定，所以选择了 react-fontawesome 的方式。&lt;/p&gt;

&lt;p&gt;顺便说一下，我的 react 并不是直接上来就&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DOMContentLoaded&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;React&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生猛开干的。
而是使用了 rails_react 的 gem 包，然后在 erb 文件中写&amp;lt;%=react_component("ComponentName") %&amp;gt;的方式来搞的。
这种方式好像还可以服务端渲染，但是具体能够有什么差异，我也没太搞明白。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Fri, 25 Dec 2020 14:43:53 +0800</pubDate>
      <link>https://ruby-china.org/topics/40744</link>
      <guid>https://ruby-china.org/topics/40744</guid>
    </item>
    <item>
      <title>bosonnlp 好像停止服务了，调用百度的 api 总是不对，业余程序员求教</title>
      <description>&lt;p&gt;我有一个小应用，用 ruby on rails 去爬一些电视剧资源
原来是使用 bosonnlp 的 api 来计算美剧标题和简介中的关键词&lt;/p&gt;

&lt;p&gt;最近发现 boson 好像是停止服务了
于是尝试使用 baidu 的 nlp api&lt;/p&gt;

&lt;p&gt;因为是业余程序员，所以先在网上抄了一段代码：&lt;/p&gt;

&lt;p&gt;可以 post 到 baidu 的那些 https 的网址上&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'json'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'net/https'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'open-uri'&lt;/span&gt;

&lt;span class="c1"&gt;#url：对应的https请求&lt;/span&gt;
&lt;span class="c1"&gt;#toSend：对应的参数{:name =&amp;gt; 'lzy'} 形式&lt;/span&gt;
   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;toSend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scheme&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"https"&lt;/span&gt;
            &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use_ssl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
            &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify_mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;VERIFY_NONE&lt;/span&gt; 
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;initheader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'Content-Type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_form_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toSend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后参考百度说明：&lt;a href="https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu" rel="nofollow" target="_blank"&gt;https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu&lt;/a&gt; 
获取 access_token&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:grant_type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'client_credentials'&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:client_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'client_id'&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:client_secret&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'client_secret'&lt;/span&gt;
&lt;span class="n"&gt;send_post&lt;/span&gt; &lt;span class="s1"&gt;'https://aip.baidubce.com/oauth/2.0/token'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功获取了 access_token
下一步需要提取关键词了，就怎么都不对了。
依据百度的说明：&lt;a href="https://ai.baidu.com/ai-doc/NLP/7k6z52ggx" rel="nofollow" target="_blank"&gt;https://ai.baidu.com/ai-doc/NLP/7k6z52ggx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;代码如下：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:access_token&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'iphone手机出现“白苹果”原因及解决办法，用苹果手机的可以看下'&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'如果下面的方法还是没有解决你的问题建议来我们门店看下成都市锦江区红星路三段99号银石广场24层01室。在通电的情况下掉进清水，这种情况一不需要拆机处理。尽快断电。用力甩干，但别把机器甩掉，主意要把屏幕内的水甩出来。如果屏幕残留有水滴，干后会有痕迹。^H3 放在台灯，射灯等轻微热源下让水分慢慢散去。'&lt;/span&gt;
&lt;span class="n"&gt;send_post&lt;/span&gt; &lt;span class="s1"&gt;'https://aip.baidubce.com/rpc/2.0/nlp/v1/keyword'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;得到的结果却总是：{"error_code"=&amp;gt;100, "error_msg"=&amp;gt;"Invalid parameter"}&lt;/p&gt;

&lt;p&gt;不知道我是差了哪一步？
请大家帮忙指点一下。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Fri, 16 Oct 2020 12:15:04 +0800</pubDate>
      <link>https://ruby-china.org/topics/40484</link>
      <guid>https://ruby-china.org/topics/40484</guid>
    </item>
    <item>
      <title>最近在用 VS Code 玩儿 Flutter，在跑 Ruby on Rails 的时候总觉的非常不顺手</title>
      <description>&lt;p&gt;有没有 vscode 玩儿 ruby on rails 的指南？
还是这东西就不适合 ruby on rails？&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Wed, 11 Mar 2020 10:14:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/39578</link>
      <guid>https://ruby-china.org/topics/39578</guid>
    </item>
    <item>
      <title>发个牢骚，刚刚被 CarrierWave 给玩儿了一下</title>
      <description>&lt;p&gt;我使用 mongoid，用 carrierwave 存储信息。
前面犯二，将一个图片格式的信息，通过 embed 嵌入表的形式存储了。每次做操作的时候都非常痛苦。
今天下决心将所有的数据，重新导到了外面，变成了一个独立的表，从 embeds_many，变成了 has_many
结果发现，所有的图片都取不出来了。
还为此打电话去七牛。&lt;/p&gt;

&lt;p&gt;各种方法都试了一遍，最后突然想起来，carrierwave 的路径名，是自己生成的。
数据库里面只有一个字段，就是最终的文件名。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;store_dir&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;mounted_as&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;uploader 模块中有上面这个函数。
我重新倒了一遍数据库，model.id 变化了。
于是原来存储的所有文件，路径都错了。&lt;/p&gt;

&lt;p&gt;还在折腾中。应该问题不大了。&lt;/p&gt;

&lt;p&gt;切忌，尽量少在 mongid 里面使用嵌入表，查询修改都很麻烦。
在使用 carrierwave 的时候，各种文件名，都是计算出来的。比如远程的 url，就是路径加上数据库字段里面存储的文件名。
如果有 avatar 之类的图像版本，就再把这个前缀加到文件名里面去。就是这样神奇。&lt;/p&gt;

&lt;p&gt;一直希望可以在 mongoid 里面使用 ActiveStorage，不过这么长时间了，好像一直都没有人去折腾。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Fri, 06 Mar 2020 17:53:37 +0800</pubDate>
      <link>https://ruby-china.org/topics/39569</link>
      <guid>https://ruby-china.org/topics/39569</guid>
    </item>
    <item>
      <title>carrierwave 在备份的数据库上，无法获得 url</title>
      <description>&lt;p&gt;carrierwave 用了一段时间
通过 mount_uploader :picture, PictureUploader 工作。
信息是存在数据了中 picture_filename 字段里面，然后再配合着相关的云端配置来获取正确的 url
我现在出现了一个奇怪的问题，我把一个数据库迁移到了一个新的应用中，并还原的代码，picture_filename 字段里面的内容也是正确的。
但是不知道为什么，在取 picture.url 的时候，返回的永远是 nil。
检查了各处代码，都是照着原来可以工作的代码复制的，包括 config/initializers/carrierwave.rb
/app/uploaders/picture_uploader.rb
但是原来的数据就是读不出来。
数据在数据库里面的 picture_filename 里面，可以看到。就是在命令行就读不出来。
在原来的应用中没有问题，可以使用。&lt;/p&gt;

&lt;p&gt;不知道影响 carrierwave 还有哪些因素。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Tue, 18 Feb 2020 15:30:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/39511</link>
      <guid>https://ruby-china.org/topics/39511</guid>
    </item>
    <item>
      <title>业余程序员，想要找一个完整的 GraphQL 的教程和案例</title>
      <description>&lt;p&gt;我现在只能算是一个业余程序员了。
想要找一些 GraphQL 完整的教程和案例。
网上很多好像都是一些 get start 之类的东西。
详细的，也多是 nodejs 的，不是 rails 的。
我现在可以建立简单的 graphql，但是每次可以返回一个记录。
但是返回多个记录，分页，查询，修改，登陆相关的，还不太会玩儿。
本站的一些相关帖子，使用的版本太旧，参考价值已经降低了。&lt;/p&gt;

&lt;p&gt;请多多帮忙。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:person&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;PersonType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;required: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:)&lt;/span&gt;
    &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PersonType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;null: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;people&lt;/span&gt;
    &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我照着网上的例子，把 query 写成这样。
curl -XPOST -d 'query={person(id:6) {id name age desc}}'  &lt;a href="http://localhost:3000/graphql" rel="nofollow" target="_blank"&gt;http://localhost:3000/graphql&lt;/a&gt;
可以工作&lt;/p&gt;

&lt;p&gt;curl -XPOST -d 'query={people {person{name}}}'  &lt;a href="http://localhost:3000/graphql" rel="nofollow" target="_blank"&gt;http://localhost:3000/graphql&lt;/a&gt;
就出不来了。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Sun, 09 Feb 2020 18:03:21 +0800</pubDate>
      <link>https://ruby-china.org/topics/39492</link>
      <guid>https://ruby-china.org/topics/39492</guid>
    </item>
    <item>
      <title>Ruby-vips 继续，尝试一了下 carrierwave-vips</title>
      <description>&lt;p&gt;在 Gemfile 中添加：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'carrierwave-vips'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在 uploader 中添加：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;CarrierWave&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vips&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;各种 resize，version 和原来没有什么差异，这里主要说一下添加水印，也就是 watermark&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="ss"&gt;:make_watermark&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'film.png'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_watermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;manipulate!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;composite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vips&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_from_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;gravity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'south-east'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;height&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:over&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里有一个小坑，Rails.root.join 返回的是一个 pathname 而不是简单地 string。mini_magick 是可以认可这种形式的，但是 vips 不行，所以需要在 new_from_file 的参数里面加上 to_s 的 method。&lt;/p&gt;

&lt;p&gt;趟过了这个坑，一行搞定。&lt;/p&gt;

&lt;p&gt;在 uploader 中，如果需要对图像进行相对比较复杂的处理，则需要使用到 manipulate! 方法。可以取出 image 进行操作。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Sun, 31 Mar 2019 20:42:57 +0800</pubDate>
      <link>https://ruby-china.org/topics/38331</link>
      <guid>https://ruby-china.org/topics/38331</guid>
    </item>
    <item>
      <title>Ruby-vips 下通过 composite 进行 watermark 测试</title>
      <description>&lt;p&gt;最开始处理图像都是使用 rmagick，后来说是 rmagick 内存泄漏，就开始使用 mini_magick。
最近，看到 active_storage 里面提到了一种新的图像处理库，vips。&lt;/p&gt;

&lt;p&gt;于是打开看了看，发现 vips 的效率奇高，基本上比 mini_magick 快上很多。
所有 vips 的 github 库，都写着 benchmark，各种速度比较。
于是就拿过来玩耍了一下，测试了一下水印。&lt;/p&gt;

&lt;p&gt;composite 函数，就是合成。
基本流程应该是这样的：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'vips'&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Vips&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_from_file&lt;/span&gt; &lt;span class="s1"&gt;'DSC00536.JPG'&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt; &lt;span class="mf"&gt;500.0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;width&lt;/span&gt;
&lt;span class="n"&gt;logo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Vips&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_from_file&lt;/span&gt; &lt;span class="s1"&gt;'film.png'&lt;/span&gt;
&lt;span class="n"&gt;logo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gravity&lt;/span&gt; &lt;span class="s1"&gt;'south-east'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;height&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;composite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:over&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write_to_file&lt;/span&gt; &lt;span class="s1"&gt;'watermarked.jpg'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里面，需要注意的是 composite 中的参数，blend_mode
具体的解释如下：
&lt;a href="https://github.com/libvips/ruby-vips/blob/master/lib/vips/blend_mode.rb" rel="nofollow" target="_blank"&gt;https://github.com/libvips/ruby-vips/blob/master/lib/vips/blend_mode.rb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;下面是相关的各种实验数据附件：
原始图片：
&lt;img src="https://l.ruby-china.com/photo/2019/e7b6932a-b9c9-47ec-82f0-0fe6224898fc.jpg!large" title="" alt=""&gt;
水印的 logo：
&lt;img src="https://l.ruby-china.com/photo/2019/9caf0c95-771a-4ade-b588-718a03c8f16f.png!large" title="" alt=""&gt;
以及各种 blend_mode 的结果：
&lt;code&gt;:clear&lt;/code&gt; - where the second object is drawn, the first is removed
&lt;img src="https://l.ruby-china.com/photo/2019/800cf643-f2ef-40df-8b7d-a40276cd7303.jpg!large" title="" alt=""&gt;
&lt;code&gt;:source&lt;/code&gt; - the second object is drawn as if nothing were below
&lt;img src="https://l.ruby-china.com/photo/2019/e6268626-94a5-426e-8458-fc9d32ead670.jpg!large" title="" alt=""&gt;
&lt;code&gt;:over&lt;/code&gt; - the image shows what you would expect if you held two semi-transparent slides on top of each other
&lt;img src="https://l.ruby-china.com/photo/2019/dc4538a6-472f-4b22-bdc1-09d011d1c1f6.jpg!large" title="" alt=""&gt;
&lt;code&gt;:in&lt;/code&gt; - the first object is removed completely, the second is only drawn where the first was
&lt;img src="https://l.ruby-china.com/photo/2019/76deef0f-2919-4a9e-b72b-daaf8f8c3b49.jpg!large" title="" alt=""&gt;
&lt;code&gt;:out&lt;/code&gt; - the second is drawn only where the first isn't
&lt;img src="https://l.ruby-china.com/photo/2019/ac3c3126-8695-46e9-adbf-001915c01638.jpg!large" title="" alt=""&gt;
&lt;code&gt;:atop&lt;/code&gt; - this leaves the first object mostly intact, but mixes both objects in the overlapping area
&lt;img src="https://l.ruby-china.com/photo/2019/f5d39922-e0ea-42b4-aefb-295e28469f70.jpg!large" title="" alt=""&gt;
&lt;code&gt;:dest&lt;/code&gt; - leaves the first object untouched, the second is discarded completely
&lt;img src="https://l.ruby-china.com/photo/2019/c7f20231-5dab-4a82-872c-7928efe347e8.jpg!large" title="" alt=""&gt;
&lt;code&gt;:dest_over&lt;/code&gt; - like &lt;code&gt;:over&lt;/code&gt;, but swaps the arguments
&lt;img src="https://l.ruby-china.com/photo/2019/39e0c52f-112e-47a8-887c-93547eb31696.jpg!large" title="" alt=""&gt;
&lt;code&gt;:dest_in&lt;/code&gt; - like &lt;code&gt;:in&lt;/code&gt;, but swaps the arguments
&lt;img src="https://l.ruby-china.com/photo/2019/496972d6-a46d-4bae-ace7-5b6f5685fe96.jpg!large" title="" alt=""&gt;
&lt;code&gt;:dest_out&lt;/code&gt; - like &lt;code&gt;:out&lt;/code&gt;, but swaps the arguments
&lt;img src="https://l.ruby-china.com/photo/2019/c3fd20f1-b06a-4892-aa10-ff2ff74c50f3.jpg!large" title="" alt=""&gt;
&lt;code&gt;:dest_atop&lt;/code&gt; - like &lt;code&gt;:atop&lt;/code&gt;, but swaps the arguments
&lt;img src="https://l.ruby-china.com/photo/2019/de2c26c0-a63e-47bd-8c8b-fa1528a7505f.jpg!large" title="" alt=""&gt;
&lt;code&gt;:xor&lt;/code&gt; - something like a difference operator
&lt;img src="https://l.ruby-china.com/photo/2019/0591c434-0674-4724-8833-e27671a3ec95.jpg!large" title="" alt=""&gt;
&lt;code&gt;:add&lt;/code&gt; - a bit like adding the two images
&lt;img src="https://l.ruby-china.com/photo/2019/29b8ef4c-11d4-49ce-9fea-cf3fe6b22279.jpg!large" title="" alt=""&gt;
&lt;code&gt;:saturate&lt;/code&gt; - a bit like the darker of the two
&lt;img src="https://l.ruby-china.com/photo/2019/d8533656-83d2-4ace-ab84-ab8e84e33380.jpg!large" title="" alt=""&gt;
&lt;code&gt;:multiply&lt;/code&gt; - at least as dark as the darker of the two inputs
&lt;img src="https://l.ruby-china.com/photo/2019/6c3125e8-374e-4251-b5f6-55483e2c8a80.jpg!large" title="" alt=""&gt;
&lt;code&gt;:screen&lt;/code&gt; - at least as light as the lighter of the inputs
&lt;img src="https://l.ruby-china.com/photo/2019/c67a6e80-1048-477f-a9f1-64af30ba2a34.jpg!large" title="" alt=""&gt;
&lt;code&gt;:overlay&lt;/code&gt; - multiplies or screens colors, depending on the lightness
&lt;img src="https://l.ruby-china.com/photo/2019/34001f9f-9464-4959-a565-07a0a7fec433.jpg!large" title="" alt=""&gt;
&lt;code&gt;:darken&lt;/code&gt; - the darker of each component
&lt;img src="https://l.ruby-china.com/photo/2019/553fdd38-bc3f-438e-9c5c-e5f13200b64e.jpg!large" title="" alt=""&gt;
&lt;code&gt;:lighten&lt;/code&gt; - the lighter of each component
&lt;img src="https://l.ruby-china.com/photo/2019/33ec86ec-a97a-4b2c-aaff-79c337cf45da.jpg!large" title="" alt=""&gt;
&lt;code&gt;:colour_burn&lt;/code&gt; - darken first by a factor of second
&lt;img src="https://l.ruby-china.com/photo/2019/c8b832e9-03af-4252-8820-56adeee37c64.jpg!large" title="" alt=""&gt;
&lt;code&gt;:colour_dodge&lt;/code&gt; - brighten first by a factor second
&lt;img src="https://l.ruby-china.com/photo/2019/d4eba499-a94e-4174-9b7d-f58c75df866a.jpg!large" title="" alt=""&gt;
&lt;code&gt;:hard_light&lt;/code&gt; - multiply or screen, depending on lightness
&lt;img src="https://l.ruby-china.com/photo/2019/84f21527-d19d-40ca-9a3e-cfe0c13b90cd.jpg!large" title="" alt=""&gt;
&lt;code&gt;:soft_light&lt;/code&gt; - darken or lighten, depending on lightness
&lt;img src="https://l.ruby-china.com/photo/2019/e6528b0c-2ff7-462e-9340-d136cd6025a2.jpg!large" title="" alt=""&gt;
&lt;code&gt;:difference&lt;/code&gt; - difference of the two
&lt;img src="https://l.ruby-china.com/photo/2019/26c1cc67-075f-4ec0-8354-0bf0f4c74b08.jpg!large" title="" alt=""&gt;
&lt;code&gt;:exclusion&lt;/code&gt; - somewhat like &lt;code&gt;:difference&lt;/code&gt;, but lower-contrast
&lt;img src="https://l.ruby-china.com/photo/2019/83b3b579-6b95-4ed4-95dd-901d901d07d2.jpg!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Sun, 31 Mar 2019 20:41:33 +0800</pubDate>
      <link>https://ruby-china.org/topics/38330</link>
      <guid>https://ruby-china.org/topics/38330</guid>
    </item>
    <item>
      <title>被 Google Cloud Storage 搞得晕头转向</title>
      <description>&lt;p&gt;开了 google cloud 账号，领取了 google 的 300 美金测试金。
然后尝试 google cloud storage，各种不对。
总是连不上。
今天测试了一下，如果是在 google cloud 的云主机上，各种操作都是没有问题的。
bucket 需要单独授权，这个提示很清晰，并不难搞定。&lt;/p&gt;

&lt;p&gt;最终得到的结论是：
在国内电脑上，即使处于翻墙状态，google cloud 的认证也会出现连接失败的情况，还不知道怎么解决。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Tue, 19 Feb 2019 12:45:44 +0800</pubDate>
      <link>https://ruby-china.org/topics/38121</link>
      <guid>https://ruby-china.org/topics/38121</guid>
    </item>
    <item>
      <title>有人知道 gcloud 的存储怎么配置吗？</title>
      <description>&lt;p&gt;我尝试使用 carrierwave-google-storage，将内容上传到 google 云上。&lt;/p&gt;

&lt;p&gt;我已经使用了科学上网手段。&lt;/p&gt;

&lt;p&gt;对了现在有每人 300 美金的一年免费账号，不用白不用。&lt;/p&gt;

&lt;p&gt;根据提示，我去创建了 keyfile。然后怎么都连接不上。&lt;/p&gt;

&lt;p&gt;我选择的角色是对象存储管理员和存储管理员，两个都连不上。&lt;/p&gt;

&lt;p&gt;也没有地方看到任何提示信息，不知道有没有人玩儿过？&lt;/p&gt;

&lt;p&gt;我有试验了另外一种模式：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cloud&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;
&lt;span class="no"&gt;Preview&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"google/cloud/storage"&lt;/span&gt;

&lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Google&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cloud&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;project_id: &lt;/span&gt;&lt;span class="s2"&gt;"my-todo-project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;credentials: &lt;/span&gt;&lt;span class="s2"&gt;"/path/to/keyfile.json"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;依然不对，返回都是一样的：&lt;/p&gt;

&lt;p&gt;Traceback (most recent call last):&lt;/p&gt;

&lt;p&gt;1: from (irb):2&lt;/p&gt;

&lt;p&gt;Faraday::ConnectionFailed (execution expired)&lt;/p&gt;

&lt;p&gt;求助。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Fri, 01 Feb 2019 15:52:32 +0800</pubDate>
      <link>https://ruby-china.org/topics/38076</link>
      <guid>https://ruby-china.org/topics/38076</guid>
    </item>
    <item>
      <title>使用 Active Storage 往七牛上存东西，发生问题，求解</title>
      <description>&lt;p&gt;我在使用 Active_Storage 的时候，遇到了一个奇怪问题。
这么多年来，一直都在使用七牛云，做了设置：
storage.yml 里面&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;qiniu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Qiniu&lt;/span&gt;
    &lt;span class="na"&gt;access_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= Rails.application.credentials.dig(:qiniu, :access_key) %&amp;gt;&lt;/span&gt;
    &lt;span class="na"&gt;secret_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= Rails.application.credentials.dig(:qiniu, :secret_key) %&amp;gt;&lt;/span&gt;
    &lt;span class="na"&gt;bucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= Rails.application.credentials.dig(:qiniu, :bucket) %&amp;gt;&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= Rails.application.credentials.dig(:qiniu, :domain) %&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;development.rb 里面&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;active_storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:qiniu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;_form.html.erb 里面&lt;/p&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file_field&lt;/span&gt; &lt;span class="ss"&gt;:image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;direct_upload: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在上传文件的时候，却得到了这样的提示：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NameError &lt;span class="o"&gt;(&lt;/span&gt;Cannot load &lt;span class="sb"&gt;`&lt;/span&gt;Rails.config.active_storage.service&lt;span class="sb"&gt;`&lt;/span&gt;:
uninitialized constant ActiveStorage::Service::QiniuService::Qiniu&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用 local 的时候，没有问题。
七牛的全套设置，是在其他项目里面一直在用的，肯定没有问题。&lt;/p&gt;

&lt;p&gt;请问我少设置了什么吗？&lt;/p&gt;

&lt;p&gt;当我添加了：
&lt;code&gt;rb
config.active_storage.analyzers = [ ActiveStorage::Analyzer::QiniuImageAnalyzer, ActiveStorage::Analyzer::QiniuVideoAnalyzer ]
&lt;/code&gt;
之后，显示 analyzers 失败。&lt;/p&gt;

&lt;p&gt;我很喜欢用 CarrierWave 里面的 remote_url，直接抓取外面的资源，现在怎么搞？
另外，原来 carrierwave 里面，是在上传的时候，做图像处理的，还可以添加水印、圆角什么的，现在怎么搞？是不是都要到显示的时候来处理？这样的话，是不是每次显示的时候都要运算，原来是分成不同的版本存下来的，显示的时候直接调用就好了。&lt;/p&gt;

&lt;p&gt;另外，询问一下，mongoid 上怎么用这个东西？CarrierWave 是有 mongoid 的整合 gem 的。&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Sun, 24 Jun 2018 15:43:47 +0800</pubDate>
      <link>https://ruby-china.org/topics/37038</link>
      <guid>https://ruby-china.org/topics/37038</guid>
    </item>
    <item>
      <title>使用 axios.put 的时候，反馈 Can't verify CSRF token authenticity</title>
      <description>&lt;p&gt;Started PUT "/products/597074f958efe52639ad261a" for 127.0.0.1 at 2017-07-29 00:17:11 +0800
Processing by ProductsController#update as HTML
  Parameters: {"title"=&amp;gt;"abc", "desc"=&amp;gt;"hehe", "id"=&amp;gt;"597074f958efe52639ad261a", "product"=&amp;gt;{"title"=&amp;gt;"abc", "desc"=&amp;gt;"hehe"}}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms&lt;/p&gt;

&lt;p&gt;ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):&lt;/p&gt;

&lt;p&gt;我用 react 写了个例子。
get 信息的时候没有问题，但是 put 的时候，就 422 了。&lt;/p&gt;

&lt;p&gt;我尝试了添加：axios.defaults.headers.common['Authorization'] = 'L2yn79biL79xYPVV7N3997FEyLUeN9Av7DfweSocco4ircVzTs+qli8tcVgd8Hx+Y2CNRgFAPrMLAFrOxoCRsg==';
在代码中，依然无效。
请问应该怎么解决 token 的问题？&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Sat, 29 Jul 2017 00:21:57 +0800</pubDate>
      <link>https://ruby-china.org/topics/33663</link>
      <guid>https://ruby-china.org/topics/33663</guid>
    </item>
    <item>
      <title>carrierwave-mongoid 的数据，找不到了</title>
      <description>&lt;p&gt;我在一个项目中使用 carrierwave-mongoid，作为附件管理的工具&lt;/p&gt;

&lt;p&gt;在 mongodb 中，没有发现存储的相关信息在什么地方&lt;/p&gt;

&lt;p&gt;dump 了 mongodb 的数据库，到新的数据库中进行 restore&lt;/p&gt;

&lt;p&gt;原来的 picture_url，就不工作了，返回的都是 nil&lt;/p&gt;

&lt;p&gt;请问应该如何处理？&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Tue, 18 Jul 2017 17:31:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/33546</link>
      <guid>https://ruby-china.org/topics/33546</guid>
    </item>
    <item>
      <title>如何在爬虫中运行网页中的 JavaScript</title>
      <description>&lt;p&gt;我写了个爬虫程序。
但是，目标网站经常改变域名，所以会在首页中执行一个 JavaScript，从而获得当前正确的域名。
我怎么才能搞在自己的爬虫程序中，执行这段 JS，获得正确的域名呢？&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Sat, 03 Dec 2016 10:15:45 +0800</pubDate>
      <link>https://ruby-china.org/topics/31779</link>
      <guid>https://ruby-china.org/topics/31779</guid>
    </item>
    <item>
      <title>eeepub 有替代品吗？好像几年没有更新了</title>
      <description>&lt;p&gt;想要做一个 epub 生成的功能。
使用 eeepub，结果好几年没有更新的东西，和 zip 版本不兼容。
有什么简单一点儿的方法吗？&lt;/p&gt;</description>
      <author>lukefan</author>
      <pubDate>Sun, 18 Oct 2015 09:48:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/27711</link>
      <guid>https://ruby-china.org/topics/27711</guid>
    </item>
  </channel>
</rss>
