Hatena::ブログ(Diary)

130単位

2013-09-09

JS勉強会しました #mtsmhack

準備不足でコンテンツ未定なままだったのは反省点ですが、パーフェクトJavaScriptの一部を読んだりしました。

パーフェクトJavaScript

477414813X

全部読んだわけではないのですが印象などを。

  • ボリュームすごい
  • プログラミング初心者向けではない
  • 業務で必要な人はクライアントサイドJSを説明したPart3から読むといいかも
  • 前半のPartは基礎の理解と掘り下げに
  • 後半のPartは必要な際にリファレンスとして使うのがいいかも
  • jQueryの情報は1.6.2対象で若干古い
    • 例えば1.7からの .on()メソッドに対応してない

JavaScriptの学びかた

せっかくなので参加者のみなさんにJavaScriptをどうやって学んだか聞いてみました。

あらためて思うのは、JSを業務で使うにはHTMLCSSも理解しないといけませんし、これ読んでおけばいいという1冊を求めるのではなく、何冊か交互に読んだりして実践の中で身に付けるのがいいんじゃないかと思います。自分はJavaScript/jQueryに慣れたと感じるまでは約1年かかった気がします。

その他


4774153761
ノンプログラマのためのJavaScriptはじめの一歩 (WEB+DB PRESS plus)

477415489X
JavaScript徹底攻略 (WEB+DB PRESS plus)

関連記事

2013-09-03

Rails ポリモーフィック関連の関連名の命名

Railsポリモーフィック関連という機能があります。

class Picture < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
end

class Employee < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

class Product < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

ざっくりいうと、複数の親Modelに属するような子Modelの関連を抽象化してまとめる機能です。詳しくはRails Guidesや以下のリンク先を参照ください。

関連名

ここで注目したいのが、Modelを関連づける関連名です。Rails Guidesの例にある "imageable"。聞き慣れないですが、どうなんでしょう。確かにimageは動詞でもあるため文法的には間違ってなさそうです。が、実際に扱おうとすると違和感が生じてきます。

親Modelから子Modelを参照する際は通常の関連と同様に扱えます。

pictures = employee.pictures

逆に子Modelから呼び出そうとすると、以下のようになります。

employee = picture.imageable

imageable というメソッドで employee が返るのはちょっとわかりにくい気がします。

命名具体例

調べていて、関連名の付けかたには2種類あるように見受けられました。(見出しは造語です)

able接尾辞
子Model関連名親Model
Comment :commentable Article/Photo
Address :addressable Person/Company
AttachmentImage :attachable Blog/Entry
抽象名詞
子Model関連名親Model
Item :parent User/Machine
Comment :resource Diary/Book/Shop
Paste :item Snippet/Picture
Employee :work_place Office/Factory

抽象名詞のほうで"parent"や"resource"は抽象度が高く、(開発者間で納得できれば)汎用的に使えそうです。英語の意味的には"object"も使いたいところですが、object_idが予約されているため使えません。

命名比較

able接尾辞
  • able接尾辞なModuleをincludeする感じ
  • 関連名が動詞+ableなので悩まなくて済む
  • 子Modelから親Modelの呼び出しがわかりにくい
  • Rails Guideで例示されているということは推奨なのかもしれない
  • 海外のBlog記事ではable接尾辞の採用が目立つ
抽象名詞
  • 抽象名詞なClass継承する感じ(STIのような命名)
  • 適切な関連名が見つかるかどうかは対象Modelと語彙力に依存
    • ここで割と具体的な名詞を使うと他のModelに使える名詞がひとつ減る(細かいけど)
  • 子Modelから親Modelの呼び出しがまだわかりやすい
  • 日本人エンジニアは抽象名詞を採用している例が見受けられる

まとめ

特に結論はありません。初めて使ってみた印象などを書いてみました。どちらを選択するかは好みの問題だと思います。ちなみに、自分のケースでは抽象名詞を採用しました。やはり子Modelからの参照時に名詞であったほうが違和感が少ないように思えたからです。たとえ返るObjectがメソッド名と異なったとしても、ですね。(ただし命名には苦労しました…)

ご意見などあれば遠慮なくいただけるとありがたいです!


4844331566
改訂新版 基礎Ruby on Rails (IMPRESS KISO SERIES)

4797363827
Rails3レシピブック 190の技

2012-11-24

Rails4 beta さわってみたメモ #railshackathon

Rails4、先取りセミナーなんかもあったりして少しずつ浸透してきてる感がありますね。そんな中 no title に参加してて、Rails4でアプリを作ってみたりしたので、その感想とか書いてみます。不具合などはあくまで11/24時点の情報になります。

StrongParameters

  • Modelでattr_accessibleは使わない
  • ScaffoldでController に {modelname}_params というメソッドができるのでそれに倣うのがいいかも
  private
  def user_params
    params.require(:user).permit(:name, :password, :password_confirmation)
  end
  • ここで上書き許可するカラムを設定して、User.new(user_params) などとする

テスト

  • Ruby1.9本体にも入ってるminitestがデフォルトになっている
  • MiniTest::Specというクラスがあり、RSpec的記述に対応してる
    • no title
    • should が must に変わった感じ
    • context はないので使いたければaliasする必要がある
  • 個人的にデフォルト変えたくない派だったりするので、今後はRSpecでなくminitestを採用しようかと
  • ジェネレーターで生成される test/**/*_test.rb のまま書くとrails.vimのシンタックスハイライトが効かない
    • spec/**/*_spec.rb にリネーム or 生成されるようにする
    • あるいは vim の設定をいじる
  • minitest/pride を requireすることで実行結果が少しカラフルになる
  • FabricationはRails4未対応
    • activerecord4 ブランチを使う

I just pushed up a new branch called activerecord4 which should work if you are using edge rails. Point your Gemfile to that and you should be all set.

no title
  • テスト実行時fixturesを読み込ませないためには test_helper.rb の fixtures :all をコメントアウトする
  • database_cleaner gemを入れなくてもデータがクリアされてるっぽい
  • 本家database_cleanerはRails4未対応なのでforkされたものを使う
  • Guardによる自動実行
    • no title
    • guard init minitest でできるGuardfileは微妙なので書き換えるたほうが良さ気
    watch('test/test_helper.rb')  { "test" }
    watch(%r|^test/(.*)_test\.rb|)
    watch(%r{^app/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
  • Guardのwarning回避のため gem 'rb-fsevent', :require => false をGemfileに追加
  • テスト全実行すると'ruby-prof'がないといわれるため、gem 'ruby-prof' をGemfileに
    • performance_testで使われてるっぽい
    • [追記]上記はGuardで実行した場合のみ

RubyGems

問題なし
問題あり
  • Html2Haml/RubyParser
    • no title
    • 警告でるが変換できた
  • Event-calender
    • no title
    • かなり古いgem
    • generateされるルーティングさえ直せば動く
  • Socery
    • no title
    • attr_protected 関係でうまくいかない
  • Erd
    • no title
    • JS/CSSが読み込まれないのでER図見られない
    • Engineのassets周りで、Sprocketsの問題かも
  • Haml-Rails
  • Compass
    • no title
    • パスが通ってない
    • 下記をinitializersに記述して対応
Rails.configuration.assets.paths << Compass::Frameworks['compass'].stylesheets_directory

Ruby2.0

  • ruby-build をupgradeしてrbenvで2.0.0-preview1と2.0.0-devが利用可能
    • no title
    • Mac ではHomebrewでOpenSSLを入れてからインストールするのが推奨されている
brew install openssl
CONFIGURE_OPTS=--with-openssl-dir=`brew --prefix openssl` rbenv install 2.0.0-preview1
  • 起動時間など体感的に速い
  • Herokuで2.0.0.preview-1が利用可能だがデプロイでこける
    • Herokuが使ってるBundler1.2.1との相性が悪いらしい

その他

  • http://localhost:3000/rails/info/routes でルーティング確認できる
    • Routing Errorの画面も下部にルーティングが表示される
  • TurboLinks、JSなしのlink_toだけで勝手にAjaxになる
  • Timezoneがなんかおかしくて、JSTにならない
    • config/application.rb に config.time_zone = 'Tokyo'
  • Heroku assets
    • config/environments/production.rb に config.assets.compile = true
    • Compass, Bootstrap-Sass, Haml-Railsは:assetsグループに入れずにグローバルに定義

感想

約2年前のRails3がリリースされた頃、当時はRuby/Rails未経験でその上ググって出てくる英語の記事にも慣れてなくて、相当苦労した気がします。それに比べれば、Rails3.2をある程度触っていればRails4は割とスムーズに扱えるのではないかと思います。Rails本体よりも周辺Gemのほうが、まだ未対応だったりして動かないことがよくあります。遭遇したエラーが翌日には直っていたなんてこともあります。とはいえRails4対応という避けては通れないであろうミッションに、ソーシャルコーディングで参加できるチャンスがたくさんあるともいえます。実際にPull Requestしてみて、良いフィードバックが得られたりもしました。

時間に余裕のある人や新しもの好きな人は、Rails4ぜひ触ってみるといいと思います!

あわせて

※近々ギークハウス元住吉でRails4テーマに勉強会やろうかと思ってます

2012-10-18

jQuery クエリパラメータを全リンクに付加

やりたいこと

  • URLのクエリパラメータをページ内の全リンク(内部リンク)に付加してサイト内で引き継ぐ

コード

jQuery、URL Parserというライブラリを利用します。

<script type='text/javascript' src='/javascripts/jquery.js'></script>
<script type='text/javascript' src='/javascripts/purl.js'></script>
$(function(){
  if (location.search == '') {
    return;
  }
  var req_params = $.url(location.href).param();
  $('a').each(function(){
    if (/^(#|https?:|\/\/)/.test($(this).attr('href'))) {
      return;
    }
    var parsed = $(this).url();
    var old_params = (parsed.attr('query') == '') ? {} : parsed.param();
    var new_path = parsed.attr('path') + '?' + $.param($.extend(old_params, req_params));
    $(this).attr('href', new_path);
  });
});

仕様

  • リクエストURLにクエリパラメータがなければ何もしない
  • リクエストURLのクエリパラメータをハッシュ化
  • 全リンクを走査
    • href要素がフラグメントのみもしくは絶対URLであればスキップ
      • 内部リンクでも絶対URLの可能性がるためホスト名を検証したほうがいいかもしれない
    • リンクのクエリパラメータをハッシュ化
      • URL Parser のparam()メソッドはクエリパラメータがない場合 { : ''} が返るのでその回避
        • ただしマージ後文字列化した時不自然な=が入るだけで実害はないと思われる
    • リクエストURLとリンクのクエリパラメータハッシュをマージして文字列化
    • 新たに生成したパスでhref要素を上書き

※パラメータに配列が含まれていたり、リンクに同一パラメータが存在するかもしれないので、ハッシュ化してマージする仕様にした

留意点とか

  • GETメソッドのフォームにはactionにパラメータ追加しても効かない
    • hidden要素を追加する必要がある
  • Flashでのページ遷移があると効かない
  • そもそもJavaScriptオフだと効かない

※結局実運用せず見送った

2012-10-14

RSpecの書き方メモ #元住吉ハッカソン

Better Specsというサイトを題材にして、RSpecについてディスカッションしました。そのメモです。※訳ではないです

  • How to describe your methods
    • クラスマクロ(例えばActiveRecordのscope)のdescribe
      • describe '.scope_name' はクラスメソッドとかぶるので微妙
      • describe 'scope: scope_name' とscopeなのを明示するのがいいのでは
  • Test all possible cases
    • 正常系/異常系可能な限り網羅したほうがいいけど、程度にもよる
  • Use subject
    • 重複のあるexample groupと重複のないexample groupが1ファイルに混在する場合
      • 常にsubjectを使うように統一している
  • Use let and let!
    • 遅延評価されるletのほうがbeforeよりも良い
      • 複数のexampleで使われない変数もあるとき効率UP
    • beforeはあまり使わずなるべくletを使うようにしている
    • letで定義したものを別のlet内で利用してもok
    • letの中はなるべく1文で済ます
      • 複数の文が必要になる場合は素直にbeforeを使うべきでは
    • FixtureReplacementでオブジェクト生成に渡す引数をletでつくることもある
  • Mock or not to mock
    • ControllerのテストでModelをモック化すべきかどうかは一長一短
  • Use factories and not fixtures
    • なんとなく Fabrication > FactoryGirl の人が2人
  • 1つの example group で subject が複数できる場合はどうするか
    • そうならないように(テスト)設計する
    • 難しい場合はsubjectにこだわらず作業効率を優先
  • テストデータ
    • Database Cleanerなどでマスタデータ以外常にクリアした状態にする

まとめ

自分自身まだテスト書いたプロジェクト経験が少なく、書き方も定まっていないのですが、気になる点が話し合えて良かったです。

  • ユニットテスト(Modelなど)はletやsubjectを利用して書く
    • そう書けるようにシンプルにメソッドを実装する
  • 統合テスト(RequestSpec)は適切な粒度のexample groupで、その流れがテストされるのを優先して、subjectを使わずに書く
    • 複数の検証対象を"正常系"みたいな1つまとまりのitでやるのもありかなと

今後の方針としてはこんな感じでいこうかなと思いました。

関連リンク

RSpec自体の説明に良さ気な記事

元住吉ハッカソン、ギークハウス元住吉にて毎週やっておりますー