正解はもはやレール4では機能しません。私の答えは、(パスワードだけでなく)属性 を省略したいときにいつでも機能する、最もクリーンで用途の広いものだと思います。このアプローチは、さまざまな場所でモデルの個別の属性を更新する場合に必要になります。
たとえば、Stack Overflowが行うことを実行し、security
ページを介してパスワードを更新可能にしたい場合、ユーザー表示ビューを介して更新可能なプロファイルイメージと、ユーザー編集ビューを介して更新可能なユーザー情報の大部分を使用します。
1)クラスメソッドでを拡張しhash class
て、空白の値を削除します。このメソッドを使用して、更新されていないがparamsハッシュにまだ存在している空白の値を削除します。
1a)ディレクトリ内のディレクトリの下にhash.rb
ファイルを作成します。lib
ext
コマンドライン
$ mkdir lib/ext
$ touch lib/ext/hash.rb
1b)内部で、クラスをhash.rb
「作成」し、メソッドを作成します。Hash
.delete_blanks!
lib / ext / hash.rb
class Hash
def delete_blanks!
delete_if { |k, v| v.nil? }
end
end
1c)このファイル(およびlibディレクトリ全体)を、初期化子でそれを参照するレールに要求します。
config / boot.rb
# other things such as gemfiles are required here, left out for brevity
Dir['lib/**/*.rb'].each { |f| load(f) } # requires all .rb files in the lib directory
2)users#updateアクション内に、光沢のある新しいdelete_blanksを実装します。更新していない属性をparamsハッシュから削除するクラスメソッド。update_attributes
次に、 *メソッドではなく、メソッドを介してユーザーインスタンスを更新しますupdate
。
2a)まず、delete_blanksを使用しましょう!user_paramsハッシュを修正するメソッド:
app / controllers / users_controller.rb
new_params = user_params.delete_blanks!
2b)次に、メソッドを使用してインスタンスを更新しましょうupdate_attributes
(ここでも、メソッドではありませんupdate
)。
app / controllers / users_controller.rb
@user.update_attributes(new_params)
完成したusers#update
アクションは次のようになります。
app / controllers / users_controller.rb
def update
new_params = user_params.delete_blanks!
if @user.update_attributes(new_params)
redirect_to @user, notice: 'User was successfully updated.'
else
render action: 'edit' // or whatever you want to do
end
end
3)User
モデルで、すべての検証にオプションを追加しますif: :<attribute>
。これは、属性がparamsハッシュに存在する場合にのみ検証がトリガーされるようにするためです。このメソッドはparamsdelete_blanks!
ハッシュから属性を削除するため、たとえば、パスワードの検証は実行されません。delete_blanks!
また、値がnilのハッシュエントリのみが削除され、空の文字列のハッシュエントリは削除されないことにも注意してください。したがって、誰かがユーザー作成フォーム(またはパスワードのフィールドを持つ任意のフォーム)でパスワードを省略した場合、ハッシュの:passwordエントリはnilにならず、空になるため、プレゼンス検証が有効になります。ストリング:
3a)if:
すべての検証でオプションを使用します。
app / models / user.rb
VALID_EMAIL_REGEX = /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9\-.]/
validates :first_name, presence: true, if: :first_name
validates :last_name, presence: true, if: :last_name
validates :user_name, presence: true, if: :user_name
validates :email, presence: true,
uniqueness: { case_sensitive: false },
format: { with: VALID_EMAIL_REGEX }, if: :email
validates :password, length: { minimum: 6, maximum: 10 }, if: :password
以上です。これで、ユーザーモデルは、アプリ全体のさまざまなフォームで更新できます。属性のプレゼンス検証は、その属性のフィールドを含むすべてのフォームで引き続き機能します。たとえば、パスワードのプレゼンス検証は引き続きuser#create
ビューで機能します。
これは他の答えよりも冗長に見えるかもしれませんが、これが最も堅牢な方法だと思います。User
無限の数の異なるモデルで、インスタンスの無限の数の属性を個別に更新できます。新しいモデルでこれを実行する場合は、手順2a)、2b)、および3a)を繰り返す必要があることを覚えておいてください。