• Capistrano Test Site

    [Capistrano & Git] deploy時にsubmoduleも配備する

    Capistranoを使ったRailsアプリケーションのdeploy時に、Gitリポジトリのsubmoduleも同時に配備する方法をメモ。当方の環境は、capistrano 2.11.2。 方法はいたって簡単。confi [...]

  • Design book proposal thru Wordle

    [読書] ノンデザイナーズ・デザインブック

    デザインについての理解を深めたいと思っていた矢先に、「デザインについて | IDEA*IDEA」にて紹介されているのを見つけたので読んでみました。 ノンデザイナーズ・デザインブック [フルカラー新装増補版] Robin [...]

  • Knopjes

    [Mixpanel] track_links, track_formsのログがたまに記録されない場合の対処方法

    Webサイト上のユーザーの行動データを取得するために、Mixpanelというサービスを利用しています。 色々な言語に対応しているのですが、僕はAJAXを使ったサイトの分析を行うために、JavaScriptからMixpan [...]

  • LESS

    [Rails] Bundlerが「less 2.0.13」を見つけてくれなくて困ったときの話

    こんばんは。kadoppeです。最近は毎日必ずRailsを使ってWebアプリケーションの開発をしております。 そんなある日、Staging環境でbundle installコマンドを実行した時に以下のようなエラーが発生し [...]

  • Podular backbone

    これまでの「MVC」とBackbone.jsの関係について少し理解した。

    Backbone.jsのFAQに、記事タイトルの件について勉強になる内容が書かれていました。 せっかくなので、読んで理解したことを僕なりにまとめてみようと思います。 How does Backbone relate to [...]

[Capistrano & Git] deploy時にsubmoduleも配備する

0

Capistranoを使ったRailsアプリケーションのdeploy時に、Gitリポジトリのsubmoduleも同時に配備する方法をメモ。当方の環境は、capistrano 2.11.2。

方法はいたって簡単。config/deploy.rbに以下の一行を加えるだけです。

set :git_enable_submodules, 1

あとはいつも通り、cap deployコマンドを実行するだけ。

簡単ですね。それでは!


[読書] ノンデザイナーズ・デザインブック

0

デザインについての理解を深めたいと思っていた矢先に、「デザインについて | IDEA*IDEA」にて紹介されているのを見つけたので読んでみました。

目次

  • Chapter 1 ジョシュアツリーの悟り
  • Chapter 2 近接
  • Chapter 3 整列
  • Chapter 4 反復
  • Chapter 5 コントラスト
  • Chapter 6 復習
  • Chapter 7 カラーを使う
  • Chapter 8 おまけのチップス&トリック
  • Chapter 9 活字(と人生)
  • Chapter 10 活字のカテゴリー
  • Chapter 11 活字のコントラスト
  • Chapter 12 さて、わかりましたか?
  • Chapter 13 クイズの答え
  • Chapter 14 この本で使った書体

内容・感想

本書は、デザインを本職とするわけではないけど、デザインをする必要がある人のために書かれた本です。要素の配置・レイアウトや色、フォントの種類と効果に関する基礎的な知識を身に付ける事ができます。

僕自身、「デザイン」の「デ」の字も知らない状態で読み始めたのですが、たくさんのグラフィカルなデザイン例を使いながら丁寧に解説が進められていくので、特に詰まる部分もなく、一気に読み進める事ができました。Webデザインというよりかは紙のデザインを対象にしているようなのですが、素人レベルで読んでみて、Webデザインでも十分使える知識が書かれているように思いました。

私事ですが、最近になって自分たちでWebアプリケーションを開発するようになり、自分が簡単なデザインを作成したり、できあがったデザインの良し悪しを判断しなければならない状況に直面することがちょうど増えてきていました。

そんな中、前述したように「デザイン」の「デ」の字も知らないエンジニアである僕は、何が良いデザインで、何が悪いデザインなのかを判断する「ものさし」を持ち合わせておらず、非常にもどかしい思いを何度も経験することに。

本書では、レイアウトや配色のセオリーを文章で示したあと、「悪いデザイン」例とそれを改善した「良いデザイン」例を順に紹介する形でセオリーが具体的に解説されています。何が良いデザインで、何が悪いデザインであるかのイメージを、セオリーとともに頭に叩き込むことがでできる構成です。

自分の頭の中に「デザインのものさし」が形成されていくのを実感しながら読み進めることができたので、一からデザインを作成する自信はまだ無いまでも、デザインの良し悪しを判断する自信はそこそこ身に付いたように思いました。

明日からの仕事に早速役に立ちそうな予感!

まとめ

デザインができないエンジニアだって、きれいなデザインのアプリケーションを作りたいもんです。

だって自分が手塩にかけて育てた愛娘には、きちんと化粧をしてあげた状態で世の中に出ていって欲しいものじゃないですか。

そんな思いを常日頃から抱いてはいるけど、なかなか自分ではうまくできない、そういう人に是非読んでほしい一冊です。

それでは!


[Mixpanel] track_links, track_formsのログがたまに記録されない場合の対処方法

0

Webサイト上のユーザーの行動データを取得するために、Mixpanelというサービスを利用しています。

色々な言語に対応しているのですが、僕はAJAXを使ったサイトの分析を行うために、JavaScriptからMixpanelのAPIを呼び出すことが多いです。

さて、Mixpanelが提供しているAPIのなかにtrack_linkstrack_formsというものがあります。

これらはそれぞれ、「ユーザが特定のリンクをクリックした時にMixpanelにログを送信する」「ユーザーが特定のフォームをSubmitしたときにMixpanelにログを送信する」という役割を持っています。

ログの記録漏れ問題

ある日、Mixpanelの管理画面でログを確認していると、track_linkstrack_formsで送信されてくるはずのログが、きちんと記録されている場合とそうでない場合があることに気づきました。

「おかしいなぁ」と思いドキュメントを確認していると、track_linkstrack_formsの欄に以下のような記述を発見しました。

This function will wait 300ms for the Mixpanel servers to respond to the tracking request. If 300ms pass without a response, the page will be moved immediately without ensuring that the tracking request was successful. This means that your links will never break due to a Mixpanel error. To configure this timeout, please see the documentation for mixpanel.set_config() below.

Javascript – Full API – Mixpanel | Help

簡単にまとめると以下のようになります。

  • track_linkstrack_formsはMixpanelサーバからのレスポンスを300ms待つ
  • 300ms待ってレスポンスが返ってこない場合、リンククリックやFormのSubmitで起きるはずだったページ遷移を実行する
  • この場合、ログ送信が成功したかどうかは保証されない。

Mixpanelサーバの負荷やネットワークの遅延などで、ブラウザとMixpanelサーバとの一連のやり取りに300ms以上かかってしまう場合、ログが記録されない場合がある、ということですね。

Mixpanelのサーバが地理的にどこに設置されているかまでは調べていないのですが、モバイル環境のユーザーがいることなんかも考えると十分起こりえるケースなのかなと思ったりします。

対処方法

引用文にも書いてあるのですが、デフォルト「300ms」というタイムアウト時間は設定で変更できるみたいです。タイムアウト時間をより長い時間に変更することで、ログが記録される確率を上げることができそうです。

設定を変更するには、mixpanelオブジェクトの初期化時にtrack_links_timeoutというパラメータを渡してあげればよいです。ここではタイムアウト時間を「600ms」に変更しています。

mixpanel.init("YOUR_SECOND_PROJECT_TOKEN", {track_links_timeout: 600});

すでに、初期化を済ませている場合は以下のように「set_config」メソッドを呼び出せばいいみたいです。

mixpanel.set_config({track_links_timeout: 600});

※ ちなみにパラメータ名はtrack_links_timeoutですが、track_formsにも設定値は適用されるみたいです。

まとめ

こんな感じで、「ログがたまに記録されない」という問題が発生した場合、Mixpanelのタイムアウト時間を変更することで対処してみました。

注意点ですが、あまりタイムアウト時間を長くしすぎると、ユーザーがリンクをクリックしたりFormをSubmitしたときの待機時間が長くなってしまい、ユーザーに不快感を与えてしまうことになりかねません。

どれくらいのタイムアウト時間が最適なのかは、色々試行錯誤しながら見ていくしかないのかもしれませんね。

それでは。


[Rails] Bundlerが「less 2.0.13」を見つけてくれなくて困ったときの話

0

こんばんは。kadoppeです。最近は毎日必ずRailsを使ってWebアプリケーションの開発をしております。

そんなある日、Staging環境でbundle installコマンドを実行した時に以下のようなエラーが発生しました。

# bundle install
Fetching source index for http://rubygems.org/
Could not find less-2.0.13 in any of the sources

なんでも、「less」のバージョン2.0.13が見つからないからインストールできないとのこと。

ローカル開発環境では正しくインストールされているので、原因がわからず、どうしてだろうと悩んでしまいました。

色々調べながらネットをさまよい歩いた結果、Lessパッケージの全バージョンが記載されているページを発見。

よく見るとバージョン「2.0.13」の横に「yanked」と書かれているではありませんか。

「yanked」は普通に訳すと「取り除かれた」ということ、つまり廃止されたバージョンであることを意味します。廃止されたgemパッケージは、どうやらbundle installコマンドではインストールできないみたいです。

今回の現象の原因を推測すると、

  1. ローカル開発環境でbundle updateコマンドを実行。この時は「less 2.0.13」は「yanked」になっておらず正常にインストールされた。Gemfile.lockにも「less 2.0.13」が記録された。
  2. 「Less 2.0.13」が「yanked」に指定された。
  3. Staging環境でbundle installコマンドを実行。Gemfile.lockに記載されている「less 2.0.13」をインストールしようと試みるも、「yanked」が指定されているので失敗。

という感じでしょうか。再度、ローカル開発環境でbundle updateコマンドを実行した後は、Staging環境でも正常にインストールできるようになりました。

こんなことってあるんですね。
まあ、めでたしめでたし。

それでは。


これまでの「MVC」とBackbone.jsの関係について少し理解した。

0

Backbone.jsのFAQに、記事タイトルの件について勉強になる内容が書かれていました。

せっかくなので、読んで理解したことを僕なりにまとめてみようと思います。

Backbone.jsの「View」はこれまでのMVCで言う「Controller」

MVCパターンにはいくつかの実装が存在しますが、それらを比較すると、「Controller」の定義が違ったものになっていることが多いみたい。

Backbone.jsでは、「View」が、一般的に言う「Controller」の役割、つまり、UIで発生したイベントを処理して、HTMLテンプレートと共に結果をフィードバックする役割を担っています。

Backbone.jsがどうしてわざわざこれを「View」と呼んでいるというと、

We call it a View because it represents a logical chunk of UI, responsible for the contents of a single DOM element.

How does Backbone relate to “traditional” MVC?

と書いてあります。僕なりに翻訳すると

「Backbone.jsのViewは、あるDOM要素の内容をつかさどる、論理的なUIの塊を表現しているから」

という感じでしょうか。ちょっとわかりづらいですが、一般的な「MVC」で言うところの、「Controller」と「View」の結びつきが強いということなのだと思います。

Backbone.jsのMVC構造をこれまでのMVC(Rails)と比較

Backbone.jsのMVC構造/構成要素を、Railsのような一般的なサーバサイドMVCに当てはめて説明すると以下のようになるようです。(これも僕なりの翻訳)

  • Backbone.Model: RailsのModelからクラスメソッドを除いたようなもの。ビジネスロジックにおける一行のデータを表現/ラップしたもの。
  • Backbone.Collection: 複数のモデルで構成されるグループ。複数のデータのソートやフィルタリングのロジックはここに含まれる。
  • Backbone.Router: Railsにおける「routes.rb」とControllerのアクションに対応するもの。URLと機能(関数)をマッピングする役割がある。
  • Backbone.View: 再利用可能なUIの部品。大抵の場合はModelの関連付けられて用いられる。
  • Client-side Templates: Railsにおける「.html.erb」(ビュー/テンプレート)に対応。部分的なHTMLの描画を担当する。

これはわかりやすいですね。

Backbone.jsのViewは「大抵の場合はModelの関連付けられて用いられる」ということからも、これまでのMVCにおける「Controller」の役割を持っていることがわかります。

まとめ

クライアントサイドの処理は、UIを操作したことで発生したイベントの処理と、その結果をUIにフィードバックする処理で構成されます。

その特性に対応するために、これまでのMVCと比べて「Controller」が「View」との結びつきを強める方向に進んでいった結果、呼び方までも「View」に変わってしまった。その結果がBackbone.jsなんだと僕は理解しました。

みなさんはどのように理解していますか?ご意見、ご指摘等ありましたらいただけると嬉しいです。

それでは。


[Rails] Devise (2.0.4)でDEPRECATION WARNINGが発生

0

警告ネタが続きますが、どこかの誰かの役に立つかもとしれないということで。

Railsに便利な認証機能を追加してくれるプラグイン「Devise」を使っていたら「DEPRECATION WARNING」が発生したので、その時の対応についてメモ。

当方の環境はRails 3.2.1 + Devise 2.0.4。

以下が発生した警告。

DEPRECATION WARNING: Passing a block to devise_for is deprecated. Please remove the block from devise_for (only the block, the call to devise_for must still exist) and call devise_scope :user do ... end with the block instead.

警告の内容は「devise_forメソッドにブロックを渡すのは非推奨になりました。devise_forメソッドからブロックを取りのぞいて、そのブロックをdevise_scopeメソッドに渡してください。」とのこと。

routes.rbに警告されているであろうコードを発見。

devise_for :users, :controllers => {:omniauth_callbacks => "users/omniauth_callbacks"}
  delete '/users/sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session
end

これを以下のように書き換えることで警告が表示されなくなりました。

devise_for :users, :controllers => {:omniauth_callbacks => "users/omniauth_callbacks"}
devise_scope :users do
  delete '/users/sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session
end

警告メッセージがかなり丁寧に表示されていたので、迷うことなく警告を消し去ることができました。
めでたしめでたし。


[Rails] simple_formで「DEPRECATION WARNING」が発生

0

こんにちは。kadoppeです。

普段僕は、RailsのForm Helperを便利に拡張してくれる「SimpleForm」というライブラリをよく使っています。

input要素のtypeを自動的に決めてくれたり、label要素やヒントメッセージを簡単に出力できたりと非常に便利なライブラリです。

そんなある日、アプリケーション起動時に、SimpleFormによって2種類の「DEPRECATION WARNING」が発生するようになりました。今使っている方法がそのうち使えなくなるということなので早めに対処しといたのですが、その時の対処方法をメモしときます。

ちなみに当方の環境は、SimpleForm (2.0.2.dev)です。

警告一つ目

一つ目の警告はこんな感じ。

DEPRECATION WARNING: Passing a block to use is deprecated. Please use wrapper instead of use.

警告の内容は「useメソッドにブロックを渡すのは非推奨になりました。useメソッドの代わりにwrapperメソッドを使ってください」とのこと。

僕の場合、「config/initializers/simple_form.rb」で、SimpleFormが出力するFormの雛形を定義していたのですが、そこで例外が発生していたようです。

以下、修正前。

  config.wrappers :inline, :class => 'clearfix', :error_class => :error do |b|
    b.use :placeholder
    b.use :label
    b.use :tag => 'div', :class => 'input' do |ba| # ←ここが非推奨
      ()
    end
  end

修正後。

  config.wrappers :inline, :class => 'clearfix', :error_class => :error do |b|
    b.use :placeholder
    b.use :label
    b.wrapper :tag => 'div', :class => 'input' do |ba| # ← 修正。
      ()
    end
  end

警告二つ目

次。二つ目の警告はこんな感じ。

DEPRECATION WARNING: Passing :tag, :class and others to use is deprecated. Please invoke b.use :error, :wrap_with => {:tag=>:span, :class=>:"help-inline"} instead.

警告の内容は「useメソッドに:tagや:classといったパラメータを渡すのは非推奨になりました。代わりに、それらのパラメータをハッシュにまとめて:wrap_withパラメータに渡すようにしてください」とのこと。

というわけで修正前。

  config.wrappers :inline, :class => 'clearfix', :error_class => :error do |b|
    b.use :placeholder
    b.use :label
    b.wrapper :tag => 'div', :class => 'input' do |ba|  # ←ここが非推奨
      ba.use :error, :tag => :span, :class => :'help-inline'  # ←ここが非推奨
      ba.use :hint, :tag => :span, :class => :'help-block'  # ←ここが非推奨
    end
  end

修正後。

  config.wrappers :inline, :class => 'clearfix', :error_class => :error do |b|
    b.use :placeholder
    b.use :label
    b.wrapper :wrap_with => {:tag => 'div', :class => 'input'} do |ba| # ← 修正。
      ba.use :error, :wrap_with => {:tag => :span, :class => :'help-inline'}  # ← 修正。
      ba.use :hint, :wrap_with => {:tag => :span, :class => :'help-block'} # ← 修正。
    end
  end

修正完了!修正後、再度アプリケーションを起動してみると無事警告が発生しないようになっていました。

めでたしめでたし。


[Rails] to_jsonの出力結果にインスタンスメソッドの戻り値を含める

0

Railsどっぷりのkadoppeです。こんばんは。

タイトルの通り、to_jsonメソッドを呼び出すことにより得られるJSONフォーマットの文字列に、モデルクラスに定義されたインスタンスメソッドの戻り値を含める方法を紹介したいと思います。どこかの誰かの参考になれば。

方法は簡単。対象となるモデルクラスで「as_json」メソッドを以下のようにオーバライドするだけです。

class User
  def method_a
    return 'some value a'
  end
 
  def method_b
    return 'some value b'
  end
 
  ()
  def as_json(options = {}) 
    super(:methods => [:method_a, :method_b])
  end
end

as_jsonメソッドの中で、親クラスの同メソッドを呼び出しています。引数のmethodsキーに対応する値として、インスタンスメソッド名の配列を渡してやることで、json出力結果にそのメソッドの戻り値が含まれるようになります。

モデルが持つ本来のプロパティを何らかの形に加工してからJSON出力を行いたい場合に使えそうですね。

それでは。


RSpecのexampleをイテレータで量産する

0

全然大したことではないです。

RSpecのexampleを書いていると、単純な繰り返しのexampleをたくさん書く必要に迫られることがたまにあります。

例として、UserモデルのJSONオブジェクトに、期待するいくつかのキーが正しく含まれているか確かめるexampleを普通に書いてみます。

(例ででてくる「have_json」というCustom Matcherは「[rails] rspecでJSONをテストする – func09」にて紹介されていたものです。便利に使わせていただいています。ありがとうございます!)

describe User do
  let(:user) {stub_model(User)}
 
  describe "#to_json" do
    it "should have :id in response JSON" do
      user.to_json.should have_json("/id")
    end
 
    it "should have :username in response JSON" do
      user.to_json.should have_json("/username")
    end
 
    it "should have :parents in response JSON" do
      user.to_json.should have_json("/parents")
    end
 
    it "should have :children in response JSON" do
      user.to_json.should have_json("/children")
    end
  
  (略)
  end
end

一つのexampleで全部のキーの検証しちゃってもいいのですが、to_jsonメソッドの挙動をオーバーライドしているときなど、一つのキーに対して一つのexampleを丁寧に割り当てたいこともあり、その場合Specがとても縦に長くなってしまいます。DRY的にもよろしくない。

こんなとき、便利なのがeachイテレータです。eachイテレータを使うことで、以下のようにSpecを書きなおすことができます。

<pre lang="ruby">
describe User do
  let(:user) {stub_model(User)}
 
  describe "#to_json" do
    [:id, :username, :parents, :children].each do |key|
      it "should have :#{key} in response JSON" do
        user.to_json.should have_json("/#{key}")
      end
    end
  end
end

まあ、すっきり。とっても短くなりました。DRY的にもOK。RSpecの自己説明的な要素も維持できているように思います。

いかがでしょうか。最初に言ったとおり大したことではなく、単純にeachイテレータを使っただけなのですが、個人的にちょっと感動したので紹介してみました。

それではー。

参考URL

[Guard] FactoryGirlのファイルが変更されたタイミングでテストを自動的に実行する

0

Rails + RSpec + Spork + Guardを組み合わせてテストを自動化している環境において、FactoryGirlのファイルが変更されたタイミングで関連するテストを自動的に実行する方法をメモ。

方法はいたって簡単。Guardの設定ファイル「Guardfile」にFactoryGirlのファイルを監視する内容を記述すれば良いです。

こんな感じ。

guard 'rspec', :version => do
  (中略)
  watch(%r{^spec/factories/(.+)\.rb$}) do |m|
    %W[
      spec/models/#{m[1].singularize}_spec.rb
      spec/controllers/#{m[1]}_controller_spec.rb
    ]
  end
end

はい、おしまい。

こうすることで、例えば「spec/factories/users.rb」という名前のファイルを編集した場合、「spec/models/user_spec.rb」と「spec/controllers/users_controller_spec.rb」が自動的に実行されるようになります。

これでまた一段と快適な開発環境に近づきました。

それではー。

参考URL

Post navigation