Rails属性APIによる自動キャストparams


Railsアプリの一般的な慣習は、ロジックをプレーンな古いRubyオブジェクト(poros)に抽出することです.しかし、しばしばコントローラparamsから直接これらのオブジェクトにデータを渡していて、データはストリングとして入ります.
class SalesReport
  attr_accessor :start_date, :end_date, :min_items

  def initialize(params = {})
    @start_date = params[:start_date]
    @end_date = params[:end_date]
    @min_items = params[:min_items]
  end

  def run!
    # Do some cool stuff
  end
end

report = SalesReport.new(start_date: "2020-01-01", end_date: "2020-03-01", min_items: "10")

# But the data is just stored as strings :(
report.start_date
# => "2020-01-01"
report.min_items
# => "10"
おそらく、start_dateは、日付とmin_itemsとなります.独自の基本型キャストをコンストラクターに追加できます.
class SalesReport
  attr_accessor :start_date, :end_date, :min_items

  def initialize(params)
    @start_date = Date.parse(params[:start_date])
    @end_date = Date.parse(params[:end_date])
    @min_items = params[:min_items].to_i
  end

  def run!
    # Do some cool stuff
  end
end
しかし、さらに良いことに、あなたは自動的にこの鋳造を扱うためにAttributes APIを利用することができました.

用途


As of Rails 6.1, this module is technically a private API. Use at your own risk!


Rails属性APIは、ActiveRecordモデルのためにフードをタイプして、キャスト属性の下で使用されます.データベースにdatetime列を持っているモデルと、引き出されるRubyオブジェクトを持つモデルに対してクエリを実行すると、DateTimeフィールドがあります.
我々は、ActiveModel::ModelActiveModel::Attributesモジュールで混合によって我々のレポートモデルを散策することができます.
class SalesReport
  include ActiveModel::Model
  include ActiveModel::Attributes

  attribute :start_date, :date
  attribute :end_date, :date
  attribute :min_items, :integer

  def run!
    # Do some cool stuff
  end
end

report = SalesReport.new(start_date: "2020-01-01", end_date: "2020-03-01", min_items: "10")

# Now the attributes are native types!

report.start_date
# => Wed, 01 Jan 2020
report.min_items
# => 10
このパターンは、フォームオブジェクト、レポートオブジェクト、または他のモデルのILL RubyクラスのRailsアプリケーションでのBoilerplateコードを削減するために最適です.フレームワークにあなたのためにタイプキャスティングをするようにしましょう.

オプション


属性APIは自動的にほとんどのプリミティブのタイプキャストを処理します.すべての基本は覆われている.
attribute :start_date, :date
attribute :max_size, :integer
attribute :enabled, :boolean
attribute :score, :float
ボックスタイプの完全なリストはここにあります.
最もクールな部分は、タイプが彼らが受け入れるどんな種類で非常に堅牢であるということです.たとえば、ブール値型はfalse用のこれらの値のいずれかで動作します.
FALSE_VALUES = [
  false, 0,
  "0", :"0",
  "f", :f,
  "F", :F,
  "false", :false,
  "FALSE", :FALSE,
  "off", :off,
  "OFF", :OFF,
]
また、castserializeを実装する独自のカスタムタイプを登録することもできます.
ActiveRecord::Type.register(:zip_code, ZipCodeType)

class ZipCodeType < ActiveRecord::Type::Value
  def cast(value)
    ZipCode.new(value) # cast to your own ZipCode class for special handling
  end

  def serialize(value)
    value.to_s
  end
end
また、属性APIのデフォルト値を設定できます.
attribute :start_date, :date, default: 30.days.ago
attribute :max_size, :integer, default: 15
attribute :enabled, :boolean, default: true
attribute :score, :float, default: 9.75

アクティブ/モデル/タイプ 追加リソース


Rails APIドキュメント
ブログ柱: