ajaxで投稿してその結果を調べるみたいなテストでテストが通ったり通らなかったりする。投稿が反映される前に見に行くことがあるから。

feature "Posting a comment", js: true do
  scenario "as signed user" do
    comment_id = Comment.last.id + 1
    within("#new_comment") do
      fill_in 'comment[body]', with: 'コメントのテスト'
    end
    click_button '規約に同意してコメントする'
    sleep 1 # PLZ WAIT!! FIXME!!
    find("#comment_#{comment_id}").should have_content('コメントのテスト')
  end
end

CapybaraのREADMEにも書いてあるけどデフォルトは2秒待つようだけど5に変えたら行けた。(sleep 1は取りましたw)

# spec/spec_helper.rb:
RSpec.configure do |config| 
  Capybara.default_wait_time = 5
end

Facebook OAuthとかで証明書ちゃんと設定しないとSSLのエラーが出る。

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)

certifiedがgemの中に証明書持ってるので使うと楽。

$ gem install certified

stevegraham/certified · GitHub

確かsignal vs noiseで見て最近ちょっと好きな書き方。

Foo.this_is_the_long_method \
  awesome_long_argument_name,
  fuckin_annoying_long_argument

キモいって人も多いかも。絶対80文字以内じゃなきゃ嫌だってわけじゃないけど、ブログに書く時やスマホで見易いので好き。

API側も自分で作ってる時など、webmockをrequireしてるのに「本当に大丈夫かな?」と実リクエストを飛ばしたい時があるので下記。

WebMock.allow_net_connect!

残したままpushすると大惨事になるので注意が要る。

webmockがmockしてくれない

「webmock使ってるのにresponse bodyが空で帰ってくる」

webmockを勝手にhttp proxy的に捉えてて「おかしいなあ」なんてハマってたんですがwebmockはhttpをmockしてるわけじゃなくて特定のclassをmockしてるだけなんですよね。考えてみれば当たり前なんですがREADMEにちゃんと対応してるライブラリが書いてある。

Supported HTTP libraries

  • Net::HTTP and libraries based on Net::HTTP (i.e RightHttpConnection, REST Client, HTTParty)
  • HTTPClient
  • Patron
  • EM-HTTP-Request
  • Curb (currently only Curb::Easy)
  • Typhoeus (currently only Typhoeus::Hydra)
  • Excon

parallel requestが簡単にできるtyphoeusのメソッドの中で、single requestをするpostメソッドとかを使ってたら常にresponse bodyが空。(何故parallel requestのためのライブラリでsingle requestを使ったのか小一時間問い詰めたい > 俺)

ちゃんとTyphoeus::Hydraしか対応してないって書いてありますね。RestClient.postにしたらあっさり動きました。

しかし、コジャレたライブラリにチャレンジしていく姿勢は失わず行きたい!

seleniumはguard時とかにウィンドウ出てきてウザい。capybara-webkitはcapybara2系に対応してない。(reposのheadでは対応してるので次bump upされたら対応されるっぽい)

現時点ではpoltergeist一択っぽい。

ただ、Macでwebfontを読むとphantomjsがcrushするのでpatch当てる。

$ brew install phantomjs
# Gemfile:
group :test do
  gem 'poltergeist'
  gem 'rack-contrib'
end
# spec/spec_helper.rb:
require 'capybara/poltergeist'

RSpec.configure do |config|
  Capybara.javascript_driver = :poltergeist
end
# config/initializers/poltergeist.rb:
if Rails.env.test?
  require 'rack/contrib/simple_endpoint'
  Rails.application.config.middleware.insert_after Rack::Runtime, Rack::SimpleEndpoint, /\.ttf$/ do |req, res|
    ua = req.env['HTTP_USER_AGENT']                                            
    if ua =~ /Intel Mac OS X.*PhantomJS/                                       
      res.status = 403
      "Denying #{req.fullpath} to #{ua}"                                       
    else
      :pass
    end
  end
end

これは酷い。

この作業、@mreinschとペアプロでやってたんですがpoltergeistってドイツ語だそうです。ちなみに@hrysdがhidden fieldを「ハイデンフィールド」とドイツ語っぽく呼んでたのでドイツ語で何て言うのか聞いたら、「verstecktes felder」だそうです。全く違いました。どんな言語でも「ハイデンフィールド」は間違いだそうです。

Thomas on Rails。楽しげなメロディーと共に大惨事連発してます。Railsエンジニアのお父さんはお子さんとうっかり見たら心を深くえぐられそうです。

日本語版

Original Version

歌詞(日本語版)

「じこはおこるさ」

スリルなんてちょっとなら楽しみさ
でもイライラすると事故が起きる
へっちゃらさ なんて知らん顔して
走っているとそんな時

事故がほら起きるよ いきなり来る
調子乗ってやってるとバチがあたる

事故がほら 起きるよ
いい気になってると
そうさ、よそ見してるその時に
事故は 起きるものさ

思いつきでやると きっと 失敗するよ
幸運の女神は気まぐれだから
ウキウキしてるとまっさかさま
忘れないで気をつけてね いつだって

事故がほら起きるよ 突然さ
運が無い時はしょうがない
なんとかしよう

事故がもし起きたら
落ち込まないで
うまくやれるようにがんばろうよ
事故は起きるものさ

”標識はいくつもあるのにさ
大事なモノばかり見落とすね”

そんな時必ずやってくる
二度とやらなければいいけど
事故がほら起きるよ いきなり来る
調子乗ってやってると
バチがあたる

事故がほら起きるよ
いい気になってると
そうさ、よそ見してるその時に
事故は起きるものさ

事故がほら起きるよ突然さ
運が無い時はしょうがない
なんとかしよう
事故がもし起きたら
落ち込まないで

「まぁ、自信過剰だと集中力なんて
たいがい散漫になっちゃうからね」

事故だ 事故だ
忘れてると事故は起こるさ
ほーら!

Lyrics

"Accidents Will Happen"

Thrills and spills on the railway, it's a life of happiness
But sometimes impatience can lead to carelessness
Some think they are smart cats, and some just know it all
But sooner or later we all find out that

Accidents happen now and again, just when you least expect
Just when you think that life is okay, fate comes to collect
Accidents happen now and again, when people or trains get smart
If you don't concentrate on the thing that you're doing
Accidents will happen, just like that

Your best-laid plans can turn upside down if you get too confident
Sometimes you will slip and slide if that's Lady Luck's intent
One minute you're riding high, the next you're on the ground
But please remember, whatever the weather
You must take care 'cause

Accidents happen now and again, sometimes just by chance
You gotta pick yourself up and dust yourself down
Put it down to experience
Accidents happen now and again
Just don't take it all to heart
If you don't concentrate on the thing that you're doing
Accidents will happen, just like that

The warning signs are there for us to see most of the time
But sometimes we take chances and ignore the danger signs
Fate can surprise you, with no reason or rhyme
Make sure you learn your lesson you'll know better next time

Accidents happen now and again, just when you least expect
Just when you think that life is okay, fate comes to collect
Accidents happen now and again, when people or trains get smart
If you don't concentrate on the thing that you're doing
Accidents will happen, just like that

Accidents happen now and again
Sometimes just by chance
You gotta pick yourself up and dust yourself down
Put it down to experience
Accidents happen now and again
Just don't take it all to heart
If you don't concentrate on the thing that you're doing
And whatever you're doin' is not what you're thinking
Accidents, incidents
Accidents, incidents, accidents happen, just like that!

先週の日曜日にデザイナーの為のgem作成勉強会をFJORDでやりました。

RubyGemsによるデザインの再利用 // Speaker Deck

元々は@machdaさんが

「jsとかsassのmixinとかがgemになってると楽でいい。作り方教えて欲しい」

と言ってたので1人に教えるんだったら勉強会にしようと思いつきで10分ぐらいでATND建てたのでした。

デザイナーといってもみんなgitやterminal使えてrubyの環境つくれること前提って感じだったのでいきなりgem作成は厳しいかもですが、複雑化する長期プロジェクトではcssのgemによる構造化はほぼ必須かなって気がしました。

追加:

@kyokutyoさんが手順を公開されていました。

デザイナーの為のgem作成勉強会に参加しました = 2012.10.14.Sun • FIXME

怖話でcomment付ける対象なんて"怖い話"だけに決まってるじゃん!

class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.text :body
      t.references :story

      t.timestamps
    end
  end
end

余裕過ぎワロタwww

1年後・・・

"怖い漫画"・・・だと・・・!?

\( ^o^)/ オワタ

じゃ、じゃあ、comic_commentsというテーブルを・・・(レガシー直行)

commentをcommentableにする

でも大丈夫、後からでもcommentableに移行できます。今回はacts_as_commentableを使いました。

# Gemfile:
gem 'acts_as_commentable', '2.0.1'
% rails g comment

modelとmigrationでファイルを上書きしそうになるけど上書きしない。

# app/models/comment.rb:
class Comment < ActiveRecord::Base
  include ActsAsCommentable::Comment
  belongs_to :commentable, polymorphic: true, counter_cache: true
end
# app/models/story.rb:
class Story < ActiveRecord::Base
  has_many :comments, as: :commentable, dependent: :destroy
  acts_as_commentable
  attr_readonly :comments_count
end
# app/models/comic.rb:
class Comic < ActiveRecord::Base
  has_many :comments, as: :commentable, dependent: :destroy
  acts_as_commentable
  attr_readonly :comments_count
end

polymorphicかつcounter_cache使う時は、相手先をreadonlyにしとく必要があるみたいです。

class AddCommentableToComment < ActiveRecord::Migration
  def up
    rename_column :comments, :story_id, :commentable_id
    add_column :comments, :commentable_type, :string, default: 'Story'

    add_index :comments, :commentable_id
    add_index :comments, :commentable_type
  end

  def down
    rename_column :comments, :commentable_id, :story_id
    remove_column :comments, :commentable_type
  end
end

これで既にコメントが沢山あってもcommentableへの移行がバッチリ。この調子でtag, category, voteもどんどんやっていこう!

# config/deploy.rb:
set :default_stage, "staging"

こう書くとcap deployでデフォルトstagingに行くようになる。

先日、業務時間内に弊社インターンシップ中の@hrysdさんに対して不適切な発言がございましたのでここにお詫び申し上げます。

@hrysd「今作ろうとしてるgemでTwitterのgemみたいに設定出来るようにしたいんですけど、ココってどういう意味ですか?」

俺「どれ?」

@hrysd「ここのconfigurableの中のやつです。」

俺「どれどれ・・・?」

Twitter.configure do |config|
  config.consumer_key       = YOUR_CONSUMER_KEY
  config.consumer_secret    = YOUR_CONSUMER_SECRET
  config.oauth_token        = YOUR_OAUTH_TOKEN
  config.oauth_token_secret = YOUR_OAUTH_TOKEN_SECRET
end

module Twitter
  module Configurable
    attr_writer :consumer_key, :consumer_secret, :oauth_token, :oauth_token_secret

(...)

  # Convenience method to allow configuration options to be set in a block
  def configure
    yield self
    self
  end

(...)

end

@hrysd「このyieldってのが、」

俺「色気付きやがって・・・」

@hrysd「え?」

俺「こんな小洒落た設定方法・・・」

@hrysd「え?」

俺「チンカスの分際でblockで設定したいなんて早いんだよ!」

@hrysd「え~」

俺「アクセサを使え!アクセサを!」

誤)チンカス

正)人間(Human being)

大変申し訳ございませんでした。