ノンデザイナー・デザインブックを読み終えた

評判がいいので気になっていたので買ったのですが、なかなか全部読めてなかったのを、ようやく読み終わりました。いやー、さすがに良書といわれてるだけあって、感銘を受けました。

ノンデザイナー・デザインブックという名前だけあって、デザイナーさん向けではなくて、自分たちのような一般人が小綺麗なデザインを簡単に習得するには?という所が主体です。本の前半でだいたいの内容は終わってしまいます。後半は、更なる高みを求める場合はフォントの使い方に気を配ろう、みたいな感じの内容です。でもそれも重要ですね。

初心者は中央揃えに頼りがちとか、スペースがあると埋めたがるとか、結構あるあるやなーと感じました。特に勉強会の発表資料とか、割とギュウギュウに詰めてしまったりしつつも、「大事な内容だからしゃーない」と考えてそのままにしてしまっていたけれど、それだと視聴者には響いてなかったかもしれないと思いました。読みにくいですもんね…。

  • 注目するべきところと読ませたいところにコントラストをつけてはっきりさせること
  • 部分部分の線をそろえる事
  • メリハリを付ける事
  • 空白を作ることを恐れないこと
  • 大胆に配置すること

カラーの本だったからということもあり、すごく読みやすいしわかりやすかったです。本編は英語フォントをメインに語られていますが、最後の補足部分で日本語フォントについても書かれているので、参考になります。サイトを作るときや、資料を作るとき、勉強会の資料を作るときなど、活躍してくれそうなので、何度も読みたいと思いました。


Deviseを使ってテストしてるときだけvalidationが動かなかった件

Deviseを使ってユーザー認証部分を作っている訳ですが、テストのときにログインできるユーザーを作っておく必要がありますね。そこで私はspec/support/user_helper.rbを作って、いろんな権限のユーザーを作るメソッドを定義しています。

def build_user_func(user_sym, options={})
  options = {
    foo: 'default',
    bar: 'default'
  }.merge(options)
  FactoryGirl.build user_sym, options
end

def create_user_func(user_sym, options={})
  user = build_user_func(user_sym, options)
  user.confirm!
  user
end

def create_user
  create_user_func(:user, foo: 'other')
end

まぁ簡単に書くとこんな感じにしているんですが、user.confirm!しておかないとメールアドレスの確認が終わってないということでログインできないんですよ。で、!マークのメソッドだから保存されます。saveしてまたconfirm!するのも冗長かと思って、これでユーザー作っちゃえばいいやと思ってそうしてたんですが、confirm!メソッドはvalidationしないんです。before_validationの処理を追加してようやく気付きました。

というわけで直しました。

def create_user_func(user_sym, options={})
  user = build_user_func(user_sym, options)
  user.save! # 追加
  user.confirm!
  user
end

こんなの踏み抜くパターンは滅多にないと思いますが、情報共有として残しておきます。

追記:
user.save!をすると、メールアドレス確認メールが飛ぶという罠があったので、email-specの動作で問題が出てました。ので、以下のように修正。

def create_user_func(user_sym, options={})
  user = build_user_func(user_sym, options)
  user.skip_confirmation!
  user.save!
  user
end

これでOK。


Deviseのcurrent_userにActiveDecoratorが効かないパターンがあった

ActiveDecoratorはとても便利ですね。modelにview専用のメソッドを追加することができるので、変なヘルパーメソッドとか作らないで済むし、テストもやりやすいので捗ります。

module UserDecorator
  def show_hoge
    "これはダミーの#{hoge}です"
  end
end

今作っているシステムはDeviseでユーザー認証、cancanで権限管理を作っているので、viewで使えるcurrent_userにもActiveDecorator効いてるので便利やなと思っていたのですが、あるパターンでそれが効かないのがわかりました。cancanのチェックを外した部分です。

class PagesController < ApplicationController
  skip_authorization_check
end

どうもこれっぽい気がしてならない(違う可能性もある)。
たとえskip_authorization_checkをしても、普通にcurrent_userはviewで使えるのだが、デコレートだけされていない模様。対処方法がわからなかったので、とりあえず力技で対応してしまった。

- ActiveDecorator::Decorator.instance.decorate current_user
= current_user.show_hoge

回避策がわかり次第、この汚いソースを抹殺したい。


Rails4でsecrets.ymlでハマった。

まぁ完全にミスだったんですが、secrets.ymlにproduction環境のsecret_key_baseを設定するのは環境変数SECRET_KEY_BASEを使うのに、一度SSHでログインして設定して満足してしまって、永続化するのを忘れていました。それでcapistranoでデプロイしたら環境変数ないから止まってしまったというね…(開発環境だったからよかった)

# Be sure to restart your server when you modify this file.

# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!

# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.

# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.

development:
  secret_key_base: *************************************************************************************************************
test:
  secret_key_base: *************************************************************************************************************
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

どうするのがいいかと考えたのと相談した結果、/etc/profile.d/以下に設定ファイルを書くのが楽なんじゃないか?ということで、今回はそうしてみた。

export SECRET_KEY_BASE=*************************************************************************************************************

一度unicornを終了させてからcapistranoでデプロイして確認したら動くようになりました。
ただ、これだとアプリ単位で定義しようと思ったら、こうせざるを得なくなります。

export FOO_SECRET_KEY_BASE=*************************************************************************************************************
export BAR_SECRET_KEY_BASE=*************************************************************************************************************
production:
  secret_key_base: <%= ENV["FOO_SECRET_KEY_BASE"] %>
production:
  secret_key_base: <%= ENV["BAR_SECRET_KEY_BASE"] %>

本当にいいのかわからなかったので社内で相談してみたところ、まぁ昔ならいざ知らず、現在は1サーバー1アプリケーションになりつつあるし、そんなに気にしなくていいんじゃね?という意見もあり、それもそうだなぁと思いました。
あとは、dotenvというgemがあるから(Rails用のdotenv-railsもある)、それを使うのがいいんじゃないかという話もでました。dotenv-railsはまだ試してないのですが、概要を読んだところ、よさそうでした。後で試してみたいと思います。


Capybaraで要素がないことをテストする方法

要素が存在しないのをテストするとき、毎回どうやるか考えてしまうのでメモっとく。
テストはfeature specで書いています。

feature "何かしらのページ" do
  describe "とある条件だと" do
    background do
      visit foo_path
    end
    scenario "指定したIDの要素がないこと" do
      expect {
        find("#not_found_id")
      }.to raise_error(Capybara::ElementNotFound)
    end
  end
end