[前][次][番号順一覧][スレッド一覧]

rails:729

From: Kazuhiro Yoshida <moriq@m...>
Date: Sun, 04 Dec 2005 15:02:16 +0900
Subject: [rails:729] Re: 悩ましい日付型, date_select, select_date

もりきゅうです。

Hiroshi Takagi <gollum@h...> wrote:
> これは、フォームからのparams から、
> model_class のインスタンスをnew/update するタイミングで発生しますので、
> model_class 中に validate を書いても止められません。

attributes= の中ですね。
これは面白い問題ですね。調べてみました。

元の Controller を
--
class CustomerController...
  def update
    @customer.attributes = params["customer"]

    if @customer.save
      redirect_to :action => "show", :id => @customer.id
    else
      render "customer/edit"
    end
--
とすると
--
class Customer...
  def add_multiparam_errors(errors)
    errors.each do |error|
      errors.add(error.attribute, error.message)
    end
  end

class CustomerController...
  def update
    multiparam_errors = []
    begin
      @customer.attributes = params["customer"]
    rescue ActiveRecord::MultiparameterAssignmentErrors => e
      multiparam_errors.concat e.errors
    end

    if @customer.valid? && multiparam_errors.empty?
      @customer.save(false)
      redirect_to :action => "show", :id => @customer.id
    else
      @customer.add_multiparam_errors(multiparam_errors)
      render "customer/edit"
    end
--
とすればいいようです。
# @customer.valid? が @customer.errors を clear することに注意

結局 attributes= と valid? をハックすればいいので
まとめてプラグイン形式で書くと次のように書けます。
これを適用すれば元の Controller のままでok。

# AttributeAssignmentError#message の設定方法がまずいので
# initialize を上書きしています。
--
module ActiveRecord
  class AttributeAssignmentError < ActiveRecordError #:nodoc:
    def initialize(message, exception, attribute)
      super message
      @exception = exception
      @attribute = attribute
    end
  end

  class Base
    def set_attributes_with_multiparam_validation(attributes)
      begin
        set_attributes_without_multiparam_validation(attributes)
      rescue ActiveRecord::MultiparameterAssignmentErrors => e
        multiparam_errors.concat e.errors
      end
    end

    def valid_p_with_multiparam_validation
      ret = valid_p_without_multiparam_validation && multiparam_errors.empty?
      add_multiparam_errors
      ret
    end

    private
      def multiparam_errors
        @multiparam_errors ||= []
      end

      def add_multiparam_errors
        multiparam_errors.each do |error|
          errors.add(error.attribute, error.message)
        end
      end
  end
end

ActiveRecord::Base.class_eval do
  alias_method :set_attributes_without_multiparam_validation, :attributes=
  alias_method :attributes=, :set_attributes_with_multiparam_validation
  alias_method :valid_p_without_multiparam_validation, :valid?
  alias_method :valid?, :valid_p_with_multiparam_validation
end
--

----
Kazuhiro Yoshida  moriq@m...

--
ML: rails@r...
使い方: http://QuickML.com/
Web Site: http://wiki.fdiary.net/rails/
ML Archives: http://www.fdiary.net/ml/rails/

[前][次][番号順一覧][スレッド一覧]

       724 2005-12-03 12:33 [gollum@h...         ] 悩ましい日付型, date_select, select_date
       725 2005-12-03 12:49 ┣[osakanas@g...       ]                                       
       726 2005-12-03 13:42 ┃┣[kazuhiko@f...       ]                                     
       727 2005-12-03 13:59 ┃┗[gollum@h...         ]                                     
->     729 2005-12-04 07:02 ┗[moriq@m...          ]                                       
       730 2005-12-04 07:09  ┣[moriq@m...          ]                                     
       731 2005-12-04 07:30  ┣[moriq@m...          ]                                     
       733 2005-12-04 10:26  ┗[gollum@h...         ]                                     
       734 2005-12-04 11:44   ┗[moriq@m...          ]                                   
       735 2005-12-04 11:56    ┣[moriq@m...          ]                                 
       739 2005-12-04 16:49    ┗[gollum@h...         ]