【探検】Railsカラム更新のメソッド1
初めに
皆さん、初めまして。そして、明けましておめでとうございます。株式会社MUGENUP 開発部の奥田です。 今回、初めて技術ブログを書くことになりました。よろしくお願い致します。
何回かに分けてRailsのカラム更新メソッドについて書いていき、今回はupdate_attribute
とupdate_attributes
について記述します。2つのメソッドは私の環境だとactiverecord-3.2.16/lib/active_record/persistence.rb
にありました。以下の表は簡単なまとめです。
メソッド名 | validation | callback | 更新カラム数 |
---|---|---|---|
update_attribute |
なし | あり | 1つだけ |
update_attributes |
あり | あり | 複数 |
それではそれぞれのメソッドのソースコードを探検してみましょう〜!!
ActiveRecord::Persistence#update_attribute
# Updates a single attribute and saves the record. # This is especially useful for boolean flags on existing records. Also note that # # * Validation is skipped. # * Callbacks are invoked. # * updated_at/updated_on column is updated if that column is available. # * Updates all the attributes that are dirty in this object. # def update_attribute(name, value) name = name.to_s raise ActiveRecordError, "#{name} is marked as readonly" if self.class.readonly_attributes.include?(name) send("#{name}=", value) save(:validate => false) end
save(:validate => false)
となっているので、validationなしということがわかります。Callbackを起こすは英語でinvokeと表現するのですね〜。updated_at
またはupdated_on
は更新するとわざわざ記述しているので、更新しないメソッドもあるのかもしれません。驚いたのはsend("#{name}=", value)
の部分で、sendメソッドはカラム名=
をメソッドと認識することです。sendメソッドを深堀りするのも面白そうだと思いました。
ActiveRecord::Persistence#update_attributes
# Updates the attributes of the model from the passed-in hash and saves the # record, all wrapped in a transaction. If the object is invalid, the saving # will fail and false will be returned. # # When updating model attributes, mass-assignment security protection is respected. # If no +:as+ option is supplied then the +:default+ role will be used. # If you want to bypass the protection given by +attr_protected+ and # +attr_accessible+ then you can do so using the +:without_protection+ option. # def update_attributes(attributes, options = {}) # The following transaction covers any possible database side-effects of the # attributes assignment. For example, setting the IDs of a child collection. with_transaction_returning_status do self.assign_attributes(attributes, options) save end end
update_attributes
にはoptions
があるんですね〜。:without_protection
とoptions
に入れることでmass-assignmentのprotectionチェックなしにできることを初めて知りました。assign_attributes
の中も見たい気持ちはありますが、今後のネタとして取っておきます(笑)。コメントアウトで強調したいところを+
で囲っていますが、私の知らない記法でした。Markdown記法ではないようなので、要調査です。
番外編 ActiveRecord::Persistence#update_attributes!
#update_attributes
はsave
を呼んでいるのでカラム更新の失敗時に戻り値としてfalse
を返します。そして、#update_attribute
に!
をつけた#update_attributes!
の場合はカラム更新の失敗時に例外を返しますが、その中身はどうなっているのでしょう?save
が呼ばれて、!
がついてるということは・・・?
# Updates its receiver just like +update_attributes+ but calls <tt>save!</tt> instead # of +save+, so an exception is raised if the record is invalid. def update_attributes!(attributes, options = {}) # The following transaction covers any possible database side-effects of the # attributes assignment. For example, setting the IDs of a child collection. with_transaction_returning_status do self.assign_attributes(attributes, options) save! end end
予想通りですが、save!
が呼ばれていました〜。
最後に
簡単にではありましたが、Railsのカラム更新メソッドについて見てきました。この記事を読んで初めて知ったことがあれば幸いです。他にもカラム更新のメソッドはあるので、私の次回の記事でもカラム更新のメソッドを探検したいと思います。
宣伝
MUGENUP では、Rails を使いたいエンジニアを募集中です。 無限流開発、ご一緒しませんか?
大きな裁量で自社サービス開発!Rubyエンジニアをウォンテッド! - 株式会社MUGENUPの求人 - Wantedly