LoginSignup
6
6

More than 5 years have passed since last update.

Model.save が行われる直前に特定の動作をさせる

Last updated at Posted at 2013-01-28

FrogApps 技術ブログ始めました!
RailsやiOS、HTML5の情報を発信中!! → http://qiita.com/teams/frogapps

-

RailsでModelにデータを保存する際に、
「この文字列のカラムでは、前後に空白があったら除去したい」
などといったことをやりたいことがあります。

このような処理は、ActiveRecordに機能を追加することで実現できます。

lib 以下に、以下のようなコードを書く

Procを作り、その中に空白除去をする処理を書きます。
これをvalidationが行われる前に実行させます。

lib/ar_ex.rb
class ActiveRecord::Base
  def self.strip_data(*columns)
    columns.flatten!
    proc = Proc.new do
      columns.each do |column| 
        data = read_attribute(column)
        data.strip! if data.respond_to?(:strip!)
        write_attribute column, data
      end
    end
    before_validation &proc
  end
end

config/application.rb から読み込ませる

config/application.rb
require './lib/ar_ex'

Modelで呼び出す

(Entry というモデルで、title と body のカラムに対してsave時に前後の空白除去を行わせる)

app/models/Entry.rb
class Entry < ActiveRecord::Base

strip_data :title, :body
# …

consoleでの確認

(DBはsqliteです)

irb(main):001:0> e = Entry.new(:title => '   hoge   ', :body => '    fuga    ')
=> #<Entry id: nil, title: "   hoge   ", body: "    fuga    ", created_at: nil, updated_at: nil>

irb(main):002:0> e.save
   (0.1ms)  begin transaction
  SQL (12.4ms)  INSERT INTO "entries" ("body", "created_at", "title", "updated_at") 
VALUES (?, ?, ?, ?)  [["body", "fuga"], ["created_at", Mon, 28 Jan 2013 02:12:10 UTC +00:00], ["title", "hoge"], ["updated_at", Mon, 28 Jan 2013 02:12:10 UTC +00:00]]
   (0.9ms)  commit transaction
=> true

同様の処理は before_save などでもできますが、このようにするとModelに1行追加するだけで済みます。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6