2

パスワードの編集プロセスを変更したい。パスワードの編集ページには、1 つのフィールド :foo があり、ユーザーが正しく入力したかどうかを確認したいと考えています。

PasswordsController を作成し、update メソッドをオーバーライドして、:foo がデータベースと同じかどうかをテストするコードを追加しました。

def update
    self.resource = resource_class.reset_password_by_token(resource_params)

    # this is code that I added
    unless self.resource.foo == params[resource_name][:foo]
      self.resource.errors.add(:foo, "Foo not correct")
    end

    if resource.errors.empty?
      resource.unlock_access! if unlockable?(resource)
      flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
      set_flash_message(:notice, flash_message) if is_navigational_format?
      sign_in(resource_name, resource)
      respond_with resource, :location => after_resetting_password_path_for(resource)
    else
      binding.pry
      respond_with resource
    end
  end

:foo フィールドに「test」と入力するとしますが、データベースではその値は「fake」です。ビューにエラーが表示されますが (「Foo が正しくありません」)、入力した値 (「test」) ではなく、データベースからの値 (「fake」) が :foo フィールドに入力されます。

reset_password_by_token を再定義するか、カスタム メソッドを使用する必要がありますが、この問題を解決するためのより洗練された方法があるのでしょうか?

4

2 に答える 2

1

before_actionを使用してみてください(Rails のバージョンによっては before_filter の場合もあります):

class PasswordsController < ...

  before_action :check_foo, :only => :update

  ...

  private

    def check_foo
      # get resource
      # check foo
      # redirect if foo is not valid
    end

end

これを変更して、既存の を拡張することもできますRegistrationsControllerupdate前にフィルターを追加するだけで、既存の Devise 実装を再実装せずに再利用するだけです。

オブジェクトの が更新されないようにするには、ハッシュを:fooフィルター処理して、フィールドを削除してから に渡します。params:fooreset_password_by_token

def remove_foo(hash)
    hash.delete_if { |k, v| k == :foo }
end

...

self.resource = resource_class.reset_password_by_token(remove_foo(resource_params))

または、 Rails 4 または Strong Parametersを使用している場合は、許可しないでください。

于 2013-08-28T20:51:57.280 に答える