blog.waterlow.work

Ruby, Rails, js, etc...

【パーフェクトRails】コールバックをクラスに分離する

目的

パーフェクトRuby on Railsの9章の9−2「複雑なバリデーションとコールバックを整理する」を読んでいて コールバックをクラスに分離する場面ややり方がよくわからなかったのでまとめる。

パーフェクト Ruby on Rails

パーフェクト Ruby on Rails

はじめにさらっと今回の主張だけ述べて、本編に突入します。

コールバックをクラスに分離するのは必要?

  1. あってもいいとは思うけど、作る機会は少ないかも。
    作る場合はapp/modelsapp/servicesに入れておけばいいかな

「コールバックをクラスに分離する」とは何か?

Railsのドキュメントにあったソースをそのまま載せてしまいます。

class BankAccount < ActiveRecord::Base
  before_save      EncryptionWrapper.new("credit_card_number")
  after_save       EncryptionWrapper.new("credit_card_number")
  after_initialize EncryptionWrapper.new("credit_card_number")
end

class EncryptionWrapper
  def initialize(attribute)
    @attribute = attribute
  end

  def before_save(record)
    record.send("#{@attribute}=", encrypt(record.send("#{@attribute}")))
  end

  def after_save(record)
    record.send("#{@attribute}=", decrypt(record.send("#{@attribute}")))
  end

  alias_method :after_initialize, :after_save

  private
    def encrypt(value)
      # Secrecy is committed
    end

    def decrypt(value)
      # Secrecy is unveiled
    end
end

before_save EncryptionWrapper.new("credit_card_number")って書くとbefore_saveのときにEncryptionWrapper.new("credit_card_number").before_save(self)が呼ばれます。
つまり、渡されたオブジェクトに対してbefore_saveを委譲できるという機能というかapiです。

みんなやっているのか?

ひとまず参考資料をさがしてみることに。
ActiveRecord::Callbacks
9.2 Callbacks | Advanced Active Record in Rails 4 | InformIT
てめえらのRailsはオブジェクト指向じゃねえ!まずはCallbackクラス、Validatorクラスを活用しろ! - Qiita
ruby - Rails: monkey-patching ActiveRecord::Base vs creating a Module - Stack Overflow

以下の、オープンソースrailsプロジェクトがまとまっているサイトがあるのですが、コールバック用クラスの実装にであえませんでした。
Open Source Rails

GitLabで似たようなことをやっているようなソースも有りましたが、細かいところまでは読めませんでした。

今後どうしていくか

コールバックを別クラスに書くことは悪くはないのだが、そもそもコールバックの処理が肥大化していきそうで、あんまり良くないかなと思っている(ユーザ側に関係ない処理であれば良い)。
加えて、既存のrailsプロジェクトであまり行われていなさそうということも今回の調査でわかった。
よって、app/callbacksみたいなディレクトリは作らず、もしコールバックの処理が複数のクラスで共通になったり、肥大化していった場合には、いったんapp/modelsに作る。

【Ruby】【キャッシュ】dalli(memcachedのクライアントgem)を使ってみました

目的

memcachedrubymemcachedクライアントであるgemのdalliを使ってみたのでまとめ

memcached.org github.com

少し前に、キャッシュについていろいろやらないといけない機会があったのですが
キャッシュを実現するミドルウェアを触ったことがなかったため、手も足も出ないような状況になってしまいました。

これを期にキャッシュに使われるミドルウェアを触っていこうと思い
手始めにmemcachedと、rubyクライアントの中で割りと広く使われているdalliを触ってみました。 基本的な使い方と、覚えておけばどこかで役立ちそうな使い方についてまとめてみます。

基本的な使い方(インストールから)

インストールはgemのreadmeに親切に書いてあるのでその通りにやりましょう

$ brew install memcached
$ gem install dalli

使いかたもreadmeと一緒ですが、irbで以下のように叩くと試せます。

irb(main)> require 'dalli'
irb(main)> options = { namespace: 'app_v1', compress: true }
irb(main)> dc = Dalli::Client.new('localhost:11211', options)
irb(main)> dc.set('abc', 123)
irb(main)> dc.get('abc') # => 123

deleteしたり、有効期間を指定してsetするとかが出来ます

irb(main)> dc.set('abc', 123)
irb(main)> dc.delete('abc')
irb(main)> dc.get('abc') # => nil
irb(main)>
irb(main)> dc.set('abc', 123, 5)
irb(main)> dc.get('abc') # => 123
irb(main)> sleep 6
irb(main)> dc.get('abc') # => nil

覚えていて役立ちそうな使い方1(get_multi)

1つのキーに対するget、set、deleteはできるけど、複数キーはどうなの?という話。 memcachedのコマンドだと同じgetでできるみたいです。

github.com

dalliの場合はDalli::Client#get_multiを使います。

irb(main)> dc.set('abc', 123)
irb(main)> dc.set('def', 456)
dc.get_multi('abc', 'def') # => {"abc"=>123, "def"=>456}

DBと組み合わせて使うときに、N+1対策で使えそうです。

覚えていて役立ちそうな使い方2(cas)

Check And Set (or Compare And Swap)の略で、memcachedで楽観的ロックを実現するための機能です

irb(main)> dc.set('a', 'value1')
irb(main)> dc.cas('a') { 'value2' }
irb(main)> dc.get('a') # => value2
irb(main)> dc.cas('a') { |v| sleep 10 "#{v}+1" } # sleepの間に別コンソールでdc.set('a', 'value4')を実行する
=> false
irb(main)> dc.get('a') # => value4

casメソッドのブロックの中で行う処理に関しては、他者がそのキーの値を変更していない場合のみ書き込みでき
変更している場合にはfalseが返され書き込みに失敗します。
配列みたいなデータ構造があると、ロックと組み合わせてキューみたいな使い方ができるかなと思いました。

casメソッドにまかせている色々なことを、自力でやることもできます。詳細は述べませんが、以下のようにやるといろいろメソッドが追加されます。

irb(main)> require 'dalli/cas/client'

詳細は以下

dalli/client.rb at master · petergoldstein/dalli · GitHub

【DB設計】T字型ER入門

目的

T字型ER手法を勉強することになったので、概略とまとめ

データベース設計論 T字形ER―関係モデルとオジブェクト指向の統合をめざして

データベース設計論 T字形ER―関係モデルとオジブェクト指向の統合をめざして

設計の、特にデータベース設計について勉強しようと考えていた時にT字型ERというワードにたどり着きました。
前からデータベース設計の手順、手法についてはいろいろ模索してはいたのですが、あんまり体型だった手法がわからなかったので一度勉強してみることに。
概略と、現時点での思うことについてまとめます。

T字型ER手法とはなにか

データ正規形を作りながら、同時に、事業過程を分析して、かつ、プログラムのアルゴリズムを「I/O化」する技術。らしい。
mah_labさんのブログによると、Railsのテーブル設計と相性がいい、とのこと。 blog.mah-lab.com 以下のブログでは2000年ごろSIの一部で流行った、とされている。 ozamasa.hatenablog.jp

T字型ER手法の体型

以下のような体型で構成されている。

  1. エンティティを作る規準を示す
  2. エンティティを2つのクラス概念に分類する
  3. リレーションを作る規準を示す
  4. エンティティが正しい集合になっているかどうか、検証する
  5. 「多値のOR関係」と「多値のAND関係」を扱う規準を示す
  6. 「みなしエンティティ」と「概念的スーパーセット」を作る規準をしめす

これは追々記事でまとめていきましょう

最大の特徴

「関係」のモデリングのしかたに重きを置いているようです。R:リソース系、E:イベント系とすると、E-E,E-R,R-R,そして再帰的な関係と、それぞれのパターンに応じてどうテーブルを作っていけばいいのか細かに記載されています。
テーブル設計にまよったときに、やり過ぎにはなるかもしれないけれどとりあえず間違いではないテーブル設計ができるかもなとは思いました。

やり過ぎ禁物

カラムではなくテーブルで表現するというのは、時に複雑さを招いてしまうかもしれません。
例えば「都道府県」と「エリア(関東とか関西とか」というテーブルがあったとして、よくやるのは都道府県レコードにエリアidをもたせるのですが、この手法に従うと、「都道府県エリア関連テーブル」を作ってそこで関係を表す事になりそうです。(ER図書きたい)
これは、リソースの変更と関係の変更が区別できるため、関連の変更が多いテーブル(例えば会社組織とか)にかんしては有効かも知れませんが、そうでないケースもあるかなと思いました。
もう少し読んでみて、適切な場面で使っていければと思います。

まとめ

まだ全然読み切れていないのですが、T字型ER手法の現時点でのまとめでした。
しっかり理解して適切な場面で使いたいです。

なぜ実践DDDが理解できないのか

目的

実践ドメイン駆動設計を読んでいたが、思うように理解が進まないので、なんでなのかを分析する。

実践ドメイン駆動設計

実践ドメイン駆動設計

最近アプリケーションの設計をしっかりやれるようになりたいということで、これから設計を勉強するならDDDだと思い、上記の本を手にとって勉強していました。しかし読めど読めどなかなか自分の中に入ってきている感がないので、一度原因を探ってみようと思います。

参考

masawada.hatenadiary.com

なぜ実践DDDが理解できないのか

わからない用語調べすぎ

  • 調べている間に脳内メモリがリセットされてしまう。
  • そもそもわからない用語が多すぎる。
  • わからない用語を減らしていくか、わからない用語を許容してそのまま進めるか
  • 性格上ふんわりと理解しながらすすめるのはあんまり好きではない

前半が特に読みづらい

  • 実装があんまり出てこない
  • コンテキストマップ、アーキテクチャは特に全体像の話をしているため仕方ない?
  • 読む順番を変えればいいかも

実践といえどすべてのコードが書いてあるわけではない

  • 書いていないところに関しては、どんな実装になっているのかわからない

そもそもJavaがわからない

  • かんたんなコードしか載っていないといえど、Javaをさくっと読めるわけではない

UMLも読むのに時間が掛かる

  • 普段書かないんだもの…

まとめ

やること

  • 用語は1度調べて、用語集を片手に読むようにする?
  • ググるだけではなく引用先の本も読むようにする?
  • 読む順番を変えてみる?
  • エリック・エヴァンスの方も読んでみる?
  • JavaUMLを勉強しておく?

いろいろだ! 設計頑張るぞ!

【DB設計】「楽々erdレッスン」のまとめ

目的

「楽々ERDレッスン」を読んだので、そのまとめ

楽々ERDレッスン (CodeZine BOOKS)

楽々ERDレッスン (CodeZine BOOKS)

自分はRailsエンジニアをやっているのですが、アプリケーションを作るときに、設計面について苦手意識を感じています。
今回は、DBの設計について、いろんな人が薦めている上記の書籍を読んで、中身や感じたことについて、簡単ですがまとめてみます。

DB設計の手順

本書にはDB設計の手順は以下のように記述されていました。

  1. 大まかにブロック分けを行う(業務単位か部門単位)
  2. それぞれのブロックごとにイベント系を洗い出す(正規化しない)
  3. イベント系に対する正規化を行なって、リソース系を洗い出す
  4. リソース系に対する分類の洗い出しを行なって、リソース系の正規化を行う
  5. ブロック間でリソース系の統合を行い、さらに正規化を行う
  6. 導出系の整理をして、最終的な正規化を行う。

第3部のレッスンではもう少しカジュアルに、あとブロック外のことは省略されて以下の様な手順になっています。

  1. イベントを見出す
  2. リソースを抜き出す
  3. 項目を入れていく
  4. リレーションシップを設定する

ただし、はっきりイベントとわかるものがない場合もあるようで、そのへんは臨機応変にといったところでしょうか。

結局実務からの学びは大切

導出系を消す/残す、正規化する/しない、フラグにする/別テーブルにする等、やはり実際の業務フローやビジネスを反映することが大切そうです。
本の中でも売上伝票を例に、単価が時期によって変化する、顧客によって割引率がある、たくさん買うと値引きされる等、単純なヘッダディテール形式からどんどん複雑になっていく様を解説していました。

仕事意外でも、ふとレシートやwebサイト等を見た時に「どんなDB設計にしようか」と考えていると、いざというときに役立つかもなと思いました。

参考書、ブログ等

DB設計の書籍はあんまり多くはないのですが、下記のブログによさそうなものがまとまっていました。 normalse.hatenablog.jp

理論から学ぶデータベース実践入門もいいと思います。

その他以下も参考に。 blog.mah-lab.com blog.jnito.com

まとめ

設計がんばるぞ!

【読書ノート】SOFT SKILLS ソフトウェア開発者の人生マニュアル(学び方を学ぼう、後半)

目的

soft skilsに載っている独学の方法をまとめる。(後半) 前回の記事は以下

waterlow2013.hatenablog.com

soft skilsという本がちょっと前に話題になっていたのですが、その中に「学び方を学ぼう」という章があります。

SOFT SKILLS ソフトウェア開発者の人生マニュアル

SOFT SKILLS ソフトウェア開発者の人生マニュアル

以前は全体像とプロセスの前半についてまとめました。今回は後半です。

学ぶことを学ぼう

7.使い始められるようにする方法を学ぶ

学ぼうとしているものを使い始められるようにするために必要なだけの情報を仕入れて、次のステップで遊べるようにする。
Hello world!や開発環境のセットアップ等のこと。あまり遠くに行き過ぎないこと。

8.遊び回る

参考資料の全ては読まず、自分で遊んで実践してみる。小さなプロジェクトを作ってそれを試していく。 自然に疑問が生まれてくるので、それらを書き出しておく

9.役に立つことができるところまで学ぶ

8でリストアップした疑問を、参考資料を総動員して解決する。
参考資料を完全に読むことはしない。 学んでいることが、ステップ3で決めた成功基準に、何らかの形で結びついているかを確認する。

10.教える

どんな手段でもいいので人に教える。 何かを学んだということを確かに知るための方法はこれ以外にはない(らしい)。 学んだことの隙間を埋めるための手段として優れている。 例としては以下。

  • ブログ
  • YouTube動画かチュートリアルを作る
  • プレゼンテーションを行う。
  • 友人や、夫(妻)と対話する。
  • オンラインフォーラム内で質問に答える。

まとめ

普段は1つの書籍を通読するのを目標に写経するのが多いのですが、結局途中で挫折してしまうケースが大半です。 この勉強法だとそもそも通読することを目標にしていないので良いかもしれません。
次何かを勉強するときはこのステップを試してみようと思います。 他の勉強本も見直したい!

【読書ノート】SOFT SKILLS ソフトウェア開発者の人生マニュアル(学び方を学ぼう、前半)

目的

soft skilsに載っている独学の方法をまとめる。(前半)

soft skilsという本がちょっと前に話題になっていたのですが、その中に「学び方を学ぼう」という章があります。

SOFT SKILLS ソフトウェア開発者の人生マニュアル

SOFT SKILLS ソフトウェア開発者の人生マニュアル

勉強本はちょこちょこ読んではいたのですが、ここまで技術的な勉強に最適化された内容には出会ったことがなく、参考にしたいと思いました。
今回は本の内容をまとめて、今後適宜見返して自分の勉強に役立てたいと思います。 10個のステップが登場するのですが、今回は1〜6まで記載しています。

学ぶことを学ぼう

技術を身につけるために知るべき3つのこと

  1. どうすれば始められるか(最低限の基礎知識)
  2. テーマの幅(規模、何ができるか)
  3. 基礎(基本的なユースケース、コアの20%はどこか)

10ステップシステム

上記の3つ(特に2,3)を知るのは簡単ではないので以下の10ステップを用意してアプローチする。

  1. 全体像をつかむ
  2. スコープを決める
  3. 成功の基準を決める
  4. 参考資料を見つける
  5. 学習プランを作る
  6. リソースをフィルターにかける
  7. 使い始められるようにする方法を学ぶ
  8. 遊び回る
  9. 役に立つことができるところまで学ぶ
  10. 教える

1. 全体像をつかむ

ブログポストや記事を読み漁る。持っている本のイントロダクションを読む。
数時間が目安。

2.スコープを決める

今回の勉強で何をどこまでやるのかを考える。時間も考慮する。本に載っていた例は以下。

元のテーマ 適切なスコープ
C#を学ぶ 簡単なコンソールアプリケーションを作るために必要なC#言語の基礎を学ぶ
写真を学ぶ ポートレート写真を撮影するためのデジタル写真術を学ぶ
Linuxを学ぶ Ubuntu Linuxをセットアップ、インストールする方法と基本機能の使い方を学ぶ

3.成功の基準を決める

成功を定義する明確で簡潔な文をつくる、これも書籍の例を参考に

悪い成功基準 いい成功基準
デジタルカメラでいい写真が撮れるようになる デジタルカメラの全てを使うことができ、それがどういうものかを説明でき、いつ、どのような理由でそれぞれの機能を使うべきかも言えるようになる
C#の基礎が身についている C#で主要な言語機能をすべて利用している小さなアプリケーションをかけるようになる
HTMLを使ってウェブページを構築する方法を知っている HTML5を使って、インターネット上に自分の履歴書と仕事の例を表示するホームページを作れるようになる

4.参考資料を見つける

ぐぐって本やコンテンツなど勉強の際に参考になりそうなものを探す。 soft skilsに載っていた参考資料のリソースの例は以下

  • ブログポスト
  • オンラインビデオ
  • 学ぼうとしているテーマについての知識を既に持っている専門家など
  • ポッドキャスト
  • ソースコード
  • サンプルプロジェクト
  • オンラインドキュメント

5.学習プランを作る

参考資料を流し読みして、どういう順序で勉強していくかを決める
他人がどう教えているのかも参考に

6.リソースにフィルタをかける

どの参考資料を使うか決める。本であれば、レビューを見て1,2冊に絞る。

まとめ

前半は以上です。 個々の内容で真新しい物はなさそうですが、ここまでしっかりガイドライン的に書いてあるので非常に有効かなと思いました。

また、1〜6ステップを見ると、計画の時点で非常にしっかりしていることが読み取れます。
計画の重要性という点で、かなり前のものですが以下の記事を思い出しました。

teruyastar.hatenablog.com

続きは後日。