蟑螂窩

使用 SVG 將圖片做成動畫

| Comments

昨天朋友 Kay 幫我們團隊 oSolve 成員畫了一張人像插畫,覺得超像的!

oSolve Team

看了這張圖以後,覺得線條粗細一致而且線條幾乎都有分開,而且最近都在玩 SVG,突然靈機一閃,想把這張圖做成動畫, 於是經過兩個小時的努力,就變成下面這樣了:

See the Pen oSolve Team Drawing Animation by tonilin (@tonilin) on CodePen.

下面簡單描述一下怎麼把一張非向量的圖做成這樣的效果

Pygments.rb 效能調校

| Comments

最近公司的新產品 Torchpad 剛上線,一開始效能都很好,

可是在文章在 render markdown 的時候非常慢,在觀察之後,發現只有在有 fenced code 的頁面才會特別慢,

在仔細看,原來是使用者沒有輸入正確的語言格式(誤把檔案名稱當語言):

1
2
3
  ```app/assets/javascripts/angular/app.js
    app = angular.module("app", [])
  ```

正確的寫法應該是

1
2
3
  ```javascript app/assets/javascripts/angular/app.js
    app = angular.module("app", [])
  ```

第一種錯誤的寫法會讓回應時間多了 200ms,如果一個頁面裡面有 5 個這種寫錯的 fenced code,就至少會慢 1000ms,而且使用者一定會有出錯的時候。

201404 連結收集

| Comments

Ruby

TDD is dead. Long live testing

RailsConf 2014 got underway earlier this week and as always some interesting stuff has come out of the keynotes, particularly DHH’s statements on the weakness of test driven development.

Ruby on Rails 4.1 Release Notes

Highlights in Rails 4.1: Spring application preloader, config/secrets.yml, Action Pack variants, Action Mailer previews

OpenSSL Severe Vulnerability in TLS Heartbeat Extension (CVE-2014-0160)

Ruby is affected when statically compiled against a vulnerable version of OpenSSL through the standard library OpenSSL C extension.

Sync

Real-time Rails Partials

WGif

WGif is a command line tool for creating animated GIFs from YouTube videos.

zaru

Filename sanitization for Ruby

Rack::Attack!!!

Rack middleware for blocking & throttling

Rails 4.1.0 Invalid Locale 問題

| Comments

最近 Rails 4.1.0 release,在升級的時候發生了一個錯誤:

1
:zh is not a valid locale

application.rb 的 code 佷簡單:

1
2
3
4
5
module Demo
  class Application < Rails::Application
    config.i18n.default_locale = :"zh-TW"
  end
end

以前不會出錯,為什麼現在會呢?於是 Google 了一下,發現 Rails 4.1.0 會將 I18n.config.enforce_available_locales 預設為 true

enforce_available_localestrue 的情況下,只要將 locale 設為不包含在 available_locales 內的值,就會報錯。

解法佷簡單就直接在 application.rb 裡面把 enforce_available_locales 改為 false:

1
2
3
4
5
6
7
module Demo
  class Application < Rails::Application

    config.i18n.enforce_available_locales = false
    config.i18n.default_locale = :"zh-TW"
  end
end

如果想用 enforce_available_locales 但又不希望報錯呢?試著加入 available_locales 看看:

1
2
3
4
5
6
7
module Demo
  class Application < Rails::Application

    config.i18n.available_locales = [:"zh-TW"]
    config.i18n.default_locale = :"zh-TW"
  end
end

依然還是會出現一樣的錯誤 :zh is not a valid locale,奇怪,我設定的是 :"zh-TW",怎麼會報 :zh 不允許呢? 找了很久,發現在 production.rb 裡面有一行 i18n fallback:

1
2
3
  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation can not be found).
  config.i18n.fallbacks = true

把 i18n fallbacks 設為 true,在找不到 :"zh-TW" 的 locale 的時候,會接著尋找 :zh:zh 找不到才會接著找 :en

於是解決方法就很清楚了,只要連 :zh 一起 available 就可以了:

1
2
3
4
5
6
7
module Demo
  class Application < Rails::Application

    config.i18n.available_locales = [:"zh-TW", :zh]
    config.i18n.default_locale = :"zh-TW"
  end
end

開始創業,名字叫 oSolve

| Comments

從出社會以後的第一間公司離職以後,就一直跟朋友說著要創業,我們有很多想法和想做的點子,卻一直都沒有行動,沒有行動的原因是覺得自己學的東西還不夠,因此決定繼續工作,學習經驗。但是有人跟我說,創業家永遠不會滿足於自己所學,永遠都有學不完的東西,於是我離開了公司,開始跟朋友一起創業。

台灣有非常多的接案公司,使用 Ruby on Rails 開發的卻很少,更可惜的是使用 Ruby 開發 Server 配合 Mobile APP 的公司卻連一家都找不到。就我所知,Ruby 有很多方便的 Gem,可以使開發 API Server 變得非常迅速而且有系統,而大部分的 APP 都是需要跟 Server 做溝通的,如果在 Server 端的開發有 Ruby 的加持,可以節省非常多時間,讓客戶的產品能在最快的時間上線。

於是我們公司提供了 Rails + Mobile APP 開發的解決方案,主要的服務項目是:

  1. Rails 網站開發
  2. iOS/Android APP 開發
  3. Web or APP 顧問

如果有這方面的需求,可以在 oSolve 最下面的表單聯絡我們,我們會儘快跟你聯絡。

我的 Rails Template

| Comments

Github 上有非常多的 Rails template,例如 Rails Composer, RailsBricks, Bootstrappers,這些都是很好的 Template,有他們自己很棒的 Practice,但是不管這些 Template 有多好,生成出來的東西,有些還是不符合自己的需求,還是需要砍掉部分不需要的,加入一些自己習慣用的。

有鑑於每次產生出來以後還要做很多事情,所以,最近用了 Rails Apps Composer 製作了自己的 Rails template,可以一行指令就產生我自己常用的 Gems, Settings, Views…等等:

1
rails new project_name -m https://raw.github.com/tonilin/rails_recipe/master/template.rb

( project_name 可以換成你想要的專案名稱。)

需求

  • Rails 4.0
  • Ruby 2.1.0
  • RVM
  • Mysql
  • 使用 capistrano deploy
  • Server side 使用 Unicorn 當 Server

因為是自己的 Best Practice 所以就裡面只會問你資料庫帳號密碼,其他一律是用我習慣使用的,不會用一堆命令行問你資料庫想用哪種,要不要裝 Devise 之類的。如果不是你習慣用的可以 fork tonilin / rails-recipe 回去改,或是用比較有彈性的 Rails ComposerRailsBricks

有興趣自己寫 template 的,改天會開一篇文章教大家如何用 Rails Apps Composer 產生自己習慣的 Rails template。

內容

使用 Rails Apps Composer 可以讓 recipe 看起來很乾淨,看 code 就可以知道包含了什麼,所以參考 https://github.com/tonilin/rails-recipe/blob/master/roachking.rb%EF%BC%8C%E5%A4%A7%E6%A6%82%E5%8F%AF%E4%BB%A5%E7%9F%A5%E9%81%93%E5%8C%85%E4%BA%86%E4%BB%80%E9%BA%BC%E6%9D%B1%E8%A5%BF%E9%80%B2%E5%8E%BB%E3%80%82

不要使用 INT 來儲存 Facebook ID 或 Twitter ID

| Comments

今天在修一個使用者回報的 Facebook Binding 登入到錯誤帳號的問題,於是就開啟資料庫來看,發現一堆 Binding 都是綁到 Facebook 的 2147483647 這個 UID。 靠!好熟悉的數字,這不是天堂金幣的上限嗎?

這麼熟悉的數字一看就知道溢位了 Orz ,用 mysql 的話把欄位改成 BIGINT 就沒問題了,Rails 的修改方式:

1
2
3
4
5
class ModifyUidToBigIntToAuthorizations < ActiveRecord::Migration
  def change
    change_column :users, :facebook_id, :integer, :limit => 8
  end
end

至於為什麼是 limit 8,

Mysql:

active_record/connection_adapters/abstract_mysql_adapter.rblink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def extract_limit(sql_type)
  case sql_type
  when /^enum\((.+)\)/i
    $1.split(',').map{|enum| enum.strip.length - 2}.max
  when /blob|text/i
    case sql_type
    when /tiny/i
      255
    when /medium/i
      16777215
    when /long/i
      2147483647 # mysql only allows 2^31-1, not 2^32-1, somewhat inconsistently with the tiny/medium/normal cases
    else
      super # we could return 65535 here, but we leave it undecorated by default
    end
  when /^bigint/i;    8
  when /^int/i;       4
  when /^mediumint/i; 3
  when /^smallint/i;  2
  when /^tinyint/i;   1
  else
    super
  end
end

Postgresql:

active_record/connection_adapters/abstract_mysql_adapter.rblink
1
2
3
4
5
6
7
8
def extract_limit(sql_type)
  case sql_type
  when /^bigint/i;    8
  when /^smallint/i;  2
  when /^timestamp/i; nil
  else super
  end
end

使用 Babosa 配合 Friendly_id 解決中文網址問題

| Comments

FriendlyId 是用來讓 ActiveRecord 產生 Slug 的 Gem,一般 Rails App 通常是用資料庫的 id,以 SQL 資料庫來說就會是一個遞增的整數 http://example.com/users/1,這樣的網址沒有意義,會讓競爭對手知道你有多少 Record,而且要寫爬蟲也非常簡單,一直遞增數字就可以把整個網站爬完了。

為了解決這個問題,通常會產生 Slug 來當做 record 的識別,一般的用法是這樣:

user.rb
1
2
3
4
class User < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: :slugged
end

如果 slug 是唯一的,就可以用 http://example.com/users/roach-king 來讀取到唯一的 record,而不會有醜醜的網址:

1
2
3
4
5
6
user = User.create! name: "Roach King"
user.to_param #=> "roach-king"

# In UserController#show

user.friendly.find(parmas[:id])

可是這個 Gem 的設計會使用 ActiveSupport 的 parameterize,把非 a-z,0-9,- 的字元全部變成 -,於是中文字就會被吃掉了:

friendly_id/lib/friendly_id/slugged.rblink
1
2
3
def normalize_friendly_id(value)
  value.to_s.parameterize
end

為了解決這個問題,可以用另外一個 Gem babosa 來配合,他可以把 UTF-8 字元處理好,而不是都消滅:

1
"蟑 & 螂  窩".to_slug.normalize.to_s #=> "蟑螂窩"

跟 FriendlyId 配合只要把 normalize_friendly_id override 就可以了:

user.rb
1
2
3
4
5
6
7
8
9
class User < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: :slugged

  def normalize_friendly_id(input)
    input.to_s.to_slug.normalize.to_s
  end

end