Ruby勉強会を開催しました(2016#04)

今年4回目の勉強会を開催しました。
今回の参加者はやや少なめの7名でした。(先週の土曜日は会社で花見のイベントが開催されたので1週間延期しての開催です)

新入社員4名の内、1名Fさんが参加しました。(ちょっと参加率が低くて寂しいですが、次回以降に期待!)
新人Fさんには現在研修中のJavaを学習してもらっています。前にも記載したかもしれませんが、Ruby勉強会といってもRuby以外の勉強でもOKなのです。 先日Rubyの認定試験Goldを取得したS氏はこれからJavaScriptを学習すると意気込んでいました。

最近ではRailsのアプリケーションでもサーバー側のみに採用され、フロントにはJavaScriptや携帯端末のネイティブアプリという流れになりつつあるようですし。

さて、勉強会のメインカリキュラムであるRubyですが、作成中のグループウェアのGitHubリポジトリとJenkinsとが連携できるようになりました。(Old Tさんありがとうございました)
GitHubにpushすると、Jenkinsさんが自動的にテストをしてくださいます。

テストコードはまだ不十分なので、これからしっかりテストコードを書いてリファクタリングも進めていきたいと思います。

今回は稟議申請機能のコンテンツをコピーする機能と、作成中のドキュメントをCtrl+Sで保存する処理を実装しました。
ここでのポイントを簡単にご紹介いたします。

ActiveRecordモデルのインスタンスの複製

Rubyにはインスタンスを複製するメソッドが要されています。
そう、clonedupです。

dupに対して、cloneは凍結状態(freeze)や得意メソッドも複製するなどの違いがあります。

ActiveRecordのモデルを複製する場合にはインスタンス変数となっている、主キーのデータや タイムスタンプ(created_at, updated_at)に差が出てくるようです。

irb(main):002:0> role = Role.first
  Role Load (4.7ms)  SELECT  "roles".* FROM "roles"  ORDER BY "roles"."id" ASC LIMIT 1
=> #<Role id: 17, role: 0, description: "ユーザ", created_at: "2016-03-09 11:55:03", updated_at: "2016-03-09 11:55:03">


irb(main):003:0> role.clone
=> #<Role id: 17, role: 0, description: "ユーザ", created_at: "2016-03-09 11:55:03", updated_at: "2016-03-09 11:55:03">

irb(main):004:0> role.dup
=> #<Role id: nil, role: 0, description: "ユーザ", created_at: nil, updated_at: nil>

上記のようにrails consoleで試してみると、cloneメソッドのときはIDや登録、更新日時もセットされているのに対し、 dupメソッドを利用したときはIDと登録、更新日時がnilとなっています。

dupを活用する

業務システムでは既に登録されているデータを基に複製して登録作業を軽減させる方法を取ることがあります。
このときに、dupメソッドを利用することで永続化されていないActiveRecordのインスタンスを生成させることができます。

ただし、そのモデルに設定されているアソシエーションの外部キーがある場合、その外部キーはnilにはなりませんので、 注意して実装してください。

Ctrl+Sでデータを保存する

コントロールキー+Sキー(Ctrl+S)のキーを押下することによって画面上の更新ボタンをクリックするような処理を実装しました。

クロスブラウザでの確認がまだ十分ではありませんが、Windows7 IE11, Chrome, OSXのSafari, Chromeで上手くいきました。
Chromeではkeypressイベントではファイルダイアログが表示されてしまい、いろいろと試した結果keydown イベントでの判定を加えることで解決しました。

$ ->
  #******************************

  # Ctrl-S の処理

  #******************************


  $(document.body).keydown (event) ->
    return if !event.metaKey && !event.ctrlKey
    return if !(event.keyCode == 19 || event.keyCode == 83)
    event.preventDefault()
    button = $("button[data-save-on-keypress]")
    button.click() if button

フロントにJavaScriptを採用した際などに、このようなショートカットキーを活用できるのではないかと思います。