2015年1月19日 星期一

My troubleshooting of Rails on Windows

前言

Windows上安裝Linux VM, 直接在Linux環境開發Rails網站程式(我的Rails環境安裝(CentOS)), 除了在建立環境時, 可以熟悉Linux Server上的安裝設定外, 在開發完成後, 也可以直接建立正式的Web Server環境(e.g. use nginx)來做正式環境的測試.

這樣的做法, 便是在模擬Production Server的狀況, 在建立環境以及開發過程中, 就能及早發現可能會遇到的問題, 進而及早解決.

雖然我已經是這麼做了, 但有時不免會覺得等個VM開啟, 之後在console環境下寫程式, 有點累...XP...所以...我終於決定在要Windows環境上建立個Rails開發環境啦~~~

在Windows安裝Rails開發環境並不難, 安裝檔下載完後, 點一點下一步就能完成了...
本來預想, Linux上開發好的專案目錄整個載回Windows後, 下指令bundle install之後rails s就能測試網站了...但...果然發生了一連串的問題!!!
問題多半在於gem的安裝(未安裝或版本跟Linux環境略有差異)以及其相關的設定...

將問題以及解決方法筆記起來幫助自己記憶, 也分享給遇到相同狀況的人~~:)


Troubleshooting

1. bundle install時, 出現Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
這錯誤多半是在compile某段程式時, 找不到相依的程式(gem), 所以就報錯啦...
報錯的stack trace丫里丫雜很長, 好加在最後它都會說哪個gem出了什麼問題, 按照指示尋找蛛絲馬跡, 就有機會解決問題啦!

案例一
明明有libv8的gem, 怎麼報錯了呢
D:/RailsInstaller/Ruby2.1.0/bin/ruby.exe extconf.rb
creating Makefile
系統找不到指定的路徑。
系統找不到指定的路徑。
系統找不到指定的路徑。
D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/libv8-3.16.14.3/ext/libv8/builder.rb:58:in `setup_python!': libv8 requires python 2 to be installed in order to build, but it is currently not available (RuntimeError)
        from D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/libv8-3.16.14.3/ext/libv8/builder.rb:42:in `block in build_libv8!'
...
Gem files will remain installed in D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/libv8-3.16.14.3 for inspection.
Results logged to D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/extensions/x86-mingw32/2.1.0/libv8-3.16.14.3/gem_make.out
An error occurred while installing libv8 (3.16.14.3), and Bundler cannot continue.
Make sure that `gem install libv8 -v '3.16.14.3'` succeeds before bundling.
解決方法, 就在於後面的option設定
# gem install libv8 -v '3.16.14.3' -- --with-system-v8
相關說明可參考此連結: https://github.com/cowboyd/libv8#bring-your-own-v8

案例二
用到mysql的功能, 但缺了什麼設定呢
D:/RailsInstaller/Ruby2.1.0/bin/ruby.exe extconf.rb
checking for ruby/thread.h... yes
checking for rb_thread_call_without_gvl() in ruby/thread.h... yes
checking for rb_thread_blocking_region()... yes
checking for rb_wait_for_single_fd()... yes
checking for rb_hash_dup()... yes
checking for rb_intern3()... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
...
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers.  Check the mkmf.log file for more details.  You may need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=D:/RailsInstaller/Ruby2.1.0/bin/ruby
        --with-mysql-dir
        --without-mysql-dir
        --with-mysql-include
...
Gem files will remain installed in D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/mysql2-0.3.16 for inspection.
Results logged to D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/extensions/x86-mingw32/2.1.0/mysql2-0.3.16/gem_make.out
An error occurred while installing mysql2 (0.3.16), and Bundler cannot continue.

Make sure that `gem install mysql2 -v '0.3.16'` succeeds before bundling.
解決方法, 就在於安裝mysql2的套件, 需設定開發環境上的MySQL Server路徑, 讓其可成功的建置並安裝
# gem install mysql2 -v '0.3.16' -- '--with-mysql-dir="MySQL Server installed path" --with-mysql-lib="MySQL Server installed path\lib" --with-mysql-include="MySQL Server installed path\include"'

案例三
therubyracer你怎麼了???
D:/RailsInstaller/Ruby2.1.0/bin/ruby.exe extconf.rb
checking for main() in -lpthread... no
checking for v8.h... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers.  Check the mkmf.log file for more details.  You may need configuration options.
...
D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/libv8-3.16.14.3/ext/libv8/location.rb:50:in `configure': 
You have chosen to use the version of V8 found on your system (Libv8::Location::System::NotFoundError) and *not* the one that is bundle with the libv8 rubygem. 
However, it could not be located. please make sure you have a version of v8 that is compatible with 3.16.14.3 installed. 
You may need to special --with-v8-dir options if it is in a non-standard location
...
Gem files will remain installed in D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/therubyracer-0.12.1 for inspection.
Results logged to D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/extensions/x86-mingw32/2.1.0/therubyracer-0.12.1/gem_make.out
An error occurred while installing therubyracer (0.12.1), and Bundler cannot continue.
Make sure that `gem install therubyracer -v '0.12.1'` succeeds before bundling.
解決方法, 不使用therubyracer
在Gemfile裡, therubyracer預設是被註解起來的...會被註解起來, 一定有其道理, 所以不要隨便把他打開呀XD
若要使用JavaScript runtime, 可以安裝其它的runtime, e.g. Node.js
# sudo yum install nodejs -y
相關說明可參考此連結: http://stackoverflow.com/questions/18687575/why-is-the-gem-therubyracer-commented-out-by-default-in-gemfile


2. rails s後, 出現找不到什麼東西的狀況...
比如會看到的錯誤有: 找不到指定的模組, cannot load such file...etc.
就如報錯所說, 就是找不到那些東西, 所以把那些東西補齊就能解決問題啦~XD

案例一
找不到libmysql.dll
D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/mysql2-0.3.16/lib/mysql2.rb:8:in `require': 126: 找不到指定的模組。   - D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/extensions/x86-mingw32/2.1.0/mysql2-0.3.16/mysql2/mysql2.so (LoadError)
        from D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/mysql2-0.3.16/lib/mysql2.rb:8:in `'
...
解決方法, 將MySQL Server目錄裡的libmysql.dll複製到Ruby\bin的目錄下
相關說明可參考此連結: https://github.com/brianmario/mysql2#windows

案例二
tzinfo找不到data(TZInfo::DataSourceNotFound)
D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/tzinfo-1.2.2/lib/tzinfo/dat
a_source.rb:182:in `rescue in create_default_data_source': No source of timezone
 data could be found. (TZInfo::DataSourceNotFound)
Please refer to http://tzinfo.github.io/datasourcenotfound for help resolving th
is error.
        from D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/tzinfo-1.2.2/l
ib/tzinfo/data_source.rb:179:in `create_default_data_source'
        from D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/tzinfo-1.2.2/l
ib/tzinfo/data_source.rb:40:in `block in get'
...
解決方法, Gemfile加入下列gem
gem 'tzinfo-data'
細節設定請參考此連結: https://putshello.wordpress.com/2014/01/06/tzinfodatasourcenotfound-no-timezone-data-source-could-be-found/

案例三
找不到相依的bcrypt
D:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require': cannot load such file -- bcrypt_ext (LoadError)
...
解決方法, 升級bcrypt至3.1.9
# bundle update bcrypt
在Gemfile, 設定bcrypt使用3.1.9的版本
gem 'bcrypt', '~> 3.1.9'
相關說明可參考此連結: https://github.com/codahale/bcrypt-ruby/issues/102


3. Could not find a valid gem 'xxx' or Could not find gem 'xxx' ...
表示gem沒下載或安裝成功, 範例錯誤如下
ERROR:  Could not find a valid gem 'bootstrap-sass' (>= 0), here is why:
          Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/latest_specs.4.8.gz)
...
Could not find gem 'bootstrap-sass (~> 3.3.1) x86-mingw32' in the gems available on this machine.
...
解決方法, 增加一個可以下載的gem source後, 下載gem
# gem source -a http://rubygems.org/
# gem install bootstrap-sass


最後, 相依的gem都無誤後, 我要把專案的db建立起來(not migrate)
# bundle exec rake db:reset
or
# bundle exec rake db:drop
# bundle exec rake db:create
# bundle exec rake db:schema:load
# bundle exec rake db:seed
再次rails s, 並實際連到網頁, 確認是否還有類似的問題, 再去解決囉~~~


4. 網頁實際執行, 用到某些套件功能時, 出錯了...Orz
通常是某些gem的版本在windows上不支援...只能在報錯中尋找蛛絲馬跡了...

案例一
TypeError: 物件不支援此屬性或方法
用中文, google大神查不到資料呢XD, 用英文, TypeError: Object doesn't support this property or method, 就查到相關解決方案了...
解決方法, Gemfile加入下列gem
gem 'coffee-script-source', '1.8.0'
接下來執行
bundle update coffee-script-source
相關說明可參考此連結: http://stackoverflow.com/questions/28312460/object-doesnt-support-this-property-or-method-rails-windows-64bit


2015年1月18日 星期日

產險的意外險獲賠後片面被解約!!!


之前看到這則新聞, 來分享一下個人學習經驗...

產險的意外險, 通常是俗夠大碗, 不但價錢漂亮, 保障範圍也廣~~~
但...多數是「不保證續保」, 通常健康狀況改變申請過理賠, 產險公司是可以單方面決定不續保的!
保障範圍雖廣但不深, 若考量大的風險發生, 需要長期住院醫療時, 產險的意外險就有可能顧不到, 因為有的只理賠90天或180天...

其實保障內容在契約及商品條款都會清楚載明, 只是保險人員(業務員或經紀人)不一定會特別去提...



壽險公司的意外險, 價格相對高貴一些, 但其實也相對較有保障~~~
「保證續保」, 只要職業危險等級未提高至不承保, 且保戶願意繼續繳費, 多數壽險公司的商品是保證續約的, 理賠天數多半也都比較長

不管是產險還是壽險公司, 其提供的保障內容百百種, 雖大同小異, 但組合方式不同, 結果就會不同; 有的只理賠90天, 有的理賠365天; 有的有高額喪葬費, 有的有殘障年金; 有的有保證續保, 有的沒有...

除了找對人投保外, 呼應新聞的結尾, 在投保前, 還是要多多注意合約內容, 才不會吃悶虧囉~~~