雀巽の日記帳

雀巽が綴る日常の記録

Ginza.rb 第22回 に参加しました!

テーマ

Railsアプリケーション構築ガイド

みんなでこの記事を読み進めました!さっくりメモを取ってみました。

  • Arel
  • Ransack
  • 検索フォーム
  • ActiveModel
  • fields_for (View)
  • 日付や時刻の選択フォーム
  • 二重投稿の防止
  • 気になったこと
  • 感想

Arel

Ransack

  • Ransack を使うときは StrongParameter 必須
  • Ransack をは常に GET だけど URLの長さ制限とか大丈夫か?
    • 今は大丈夫(IE 2000文字くらいいける)
    • REST 的には GET で OK
    • 以下の理由から GET のほうが良い
      • URLコピペできる
      • Bookmark できる

検索フォーム

複雑な検索ロジックを組み立てるときは FatController と FatModel を避けるために、Form オブジェクトを作り検索ロジックを外出しする。

  • ActiveRecord を継承し、特定の場所 (Form) でのみ使われるオブジェクトを作る
    • 特定の場面でしか使われない Validation とかの切り出しができる
    • has_many :order_details, class_name: 'Form::OrderDetail'のようにしたらクラスを指定してhas_manyできる

ActiveModel

ActiveRecord の機能を切り出したようなモデル。Validate とか属性へのアクセスとかが簡単にできるようになっていろいろ嬉しい。

# app/models/form/base.rb
class Form::Base
  include ActiveModel::Model
  include ActiveModel::Callbacks # ここ以下は最新だと入れなくて良いかも
  include ActiveModel::Validations
  include ActiveModel::Validations::Callbacks

  def value_to_boolean(value)
    ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
  end
end

fields_for (View)

fields_forは自モデルとは異なるオブジェクトを編集する際に利用するメソッド

以下の条件を満たせば使用可能。

  1. fields_for の第一引数に渡した変数名の変数にアクセスできること
  2. 指定した変数が xxx_attributes= (xxx は変数名)という形式で更新できること

xxxx_attributesについてはaccepts_nested_attributes_for関数を利用することで追加できる。例えば、Orderモデルに、accepts_nested_attributes_for :order_details, allow_destroy: trueと宣言すると、Order.new.order_details_attributes=関数で Order の関連である OrderDetail モデルを編集できるようになる。

xxx_attributes=をベタで定義してもOK。

日付や時刻の選択フォーム

全てセレクトボックスから選択

  • date_select / datetime_select
    • Viewで日付や時刻をセレクトボックス形式で表示するにはdate_select / datetime_selectを使うけど、渡されるパラメータがゴチャゴチャしてる
    • この辺良い加減どうにかしたい

日付のみカレンダーからピックアップ

  • bootstrap3-datetimepicker-rails を導入すると、 手軽に Datepicker, DatetimePicker が使用可能
    • ロックインされそうで嫌かも
    • メンテされなくなったら非常に辛い

二重投稿の防止

  • Javascriptでサーバの二重投稿を防止する。ボタンを押下後、 disabled_withを利用して、ボタンを Disabled 状態にする
    • 決済系だとこれだとまずい
    • 二重課金とか発生してしまう可能性がある
    • サーバサイドの処理が必要 (セッションとかって誰かが言ってた)

気になったこと

  • order_details.each(&:calculate_order_detail_price)と各オブジェクト内で値を更新していたが、オブジェクトの値が書きかわるメソッドなのに!とか何かを明示的に書いてないのがキモい
    • 自分でもたまにこういうメソッド書くが、どうなんだろう
    • 副作用モリモリで気持ち悪い

感想

  • Arel はなるべく書かないようにしたい
  • Model (ActiveRecord) を継承した、Form 用オブジェクトを作るという発想はなかった
    • Rails でデフォルトで存在しないオブジェクトを作るのが難しい
      • どういうタイミングで作るのか
      • どこに作るのか
      • 知見が欲しい

いろいろな話ができて楽しかったです。Haskell についても軽く話しました。
Maybe とパターンマッチ良いよね。Haskell 良いよね。

明日のすごいH本読書会はで、Haskell における自己関手の圏の定義とかを話し合う予定。 自己関手の圏に定義された2つの自然変換、それがモノイド則を満たしているとモナドなんじゃないかと思ってるけど、合ってるかはさっぱりわかりません。

例えば、リストファンクター (関手)は[]という対象関数 (値コンストラクタ、a -> [a]) とmapという射関数から構成されている。この関手は Hask 圏から Hask 圏への自己関手となる。

ここで自然変換ってどう定義するんでしょうか。眠いからこの辺で辞める。

たぶん、returnjoinあたりのことで、return単位元とみなせて、returnjoinは結合律が成り立つのでモノイド、とかそんな感じだとは思うんだけど、いまいちしっくりこない。

早寝しよ!!