Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails の Active Record attributes API が便利

Rails の Active Record attributes API が便利

Avatar for vividmuimui

vividmuimui

November 03, 2017
Tweet

More Decks by vividmuimui

Other Decks in Programming

Transcript

  1. Rails の Active Record Rails の Active Record attributes API

    が便利 attributes API が便利 社内勉強会資料 LT 資料 2017/11/03 @vividmuimui 1
  2. Active Record attributes Active Record attributes API とは API とは

    rails5 で入った機能 release note: api document: http://guides.rubyonrails.org/5_0_release_notes.html#active-record- attributes-api http://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethod 3
  3. type クラスを定義する type クラスを定義する class EmailType < ActiveModel::Type::String # DB

    入 検索 時 変換 def serialize(value) normalize(super) end # DB 取 出 時 変換 # def deserialize(value); end private # setter 変換 def cast_value(value) normalize(super) end def normalize(value) return unless value value.downcase.remove(/\A[[:^graph:]]*/).remove(/[[:^graph:]]*\z/) end end 6
  4. model で使うよう宣言す model で使うよう宣言す る る 設定終わり class User <

    ApplicationRecord # attribute :field, :type attribute :email, :email end 8
  5. 使う 使う 検索する時にserialize されて検索される 保存するときもserialize される (main)> User.find_by(email: " [email protected]

    ") User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = '[email protected] (main)> FactoryBot.create(:user, email: " [email protected] ").email (0.4ms) BEGIN SQL (0.3ms) INSERT INTO `users` (`uid`, `identifier`, `email`, `password_digest`, `activat (8.5ms) COMMIT => "[email protected]" 9
  6. 問題 問題 現状のrails では ActiveRecord でしか使えず、ActiveModel なobject では使え ない つい最近、ActiveModel

    でも動くように実装され始めているようだが、現時 点では使えない https://github.com/rails/rails/pull/30920 12
  7. ActiveModel でも使う ActiveModel でも使う ここらへん読んで理解しつつつ gem を入れる 近い将来、rails 本体で ActiveModel

    で attributes api が使えるようにな るのでそのじゃまにならない方が良い PR にあるように、このgem で全部正しく動くわけではないので小さなモ デルでしか使わないほうが良さそう active_model_attributes https://github.com/rails/rails/pull/26728 https://karolgalanciak.com/blog/2016/12/04/introduction-to-activerecord- and-activemodel-attributes-api/ 13
  8. type クラスを定義する type クラスを定義する class EmailType < ActiveModel::Type::String # DB

    入 検索 時 変換 def serialize(value) normalize(super) end # DB 取 出 時 変換 # def deserialize(value); end private # setter 変換 def cast_value(value) normalize(super) end def normalize(value) return unless value value.downcase.remove(/\A[[:^graph:]]*/).remove(/[[:^graph:]]*\z/) end end 16
  9. model で使うよう宣言す model で使うよう宣言す る る 設定終わり class SomeModel include

    ActiveModel::Model include ActiveModelAttributes attribute :email, :email end 18
  10. 使う 使う (main)> SomeModel.new(email: " [email protected] ").email => "[email protected]" (main)>

    a = SomeModel.new => #<SomeModel:0x00007fec933324f8> (main)> a.email = " [email protected] " => " [email protected] " (main)> a.email => "[email protected]" 19