楽観的ロックを使ったRuby on Railsアプリケーションを作って動きを確かめる - @ledsun blog の続きです。
楽観的ロックで競合が起きるとActiveRecord::StaleObjectError
が起きます。
エラー画面が表示されます。
編集画面に競合エラーを表示
ActiveRecord::StaleObjectError
をハンドリングして次のように、編集画面にメッセージを表示してみましょう。
ArticlesController#update に例外処理を追加
つぎのように例外処理を追加します。
def update respond_to do |format| if @article.update(article_params) format.html { redirect_to article_url(@article), notice: "Article was successfully updated." } format.json { render :show, status: :ok, location: @article } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @article.errors, status: :unprocessable_entity } end end rescue ActiveRecord::StaleObjectError @article.reload.attributes = article_params.reject{ _1 == 'lock_version' } flash.now[:error] = 'Another user has made a change to that record since you accessed the edit form.' render :edit, status: :conflict end
やっていることは次の通りです。
- lock_versionを最新の値に更新
- 編集内容を復元
- フラッシュメッセージを設定
- 編集画面を表示
app/views/articles/edit.html.erb にフラッシュメッセージを追加
Scaffoldで生成した編集画面ではフラッシュメッセージが表示されません。
app/views/articles/edit.html.erb
にフラッシュメッセージの表示を追加します。
<p style="color: red"><%= flash[:error] %></p> <h1>Editing article</h1> <%= render "form", article: @article %> <br> <div> <%= link_to "Show this article", @article %> | <%= link_to "Back to articles", articles_path %> </div>
一番上の行です。
なにも考えずにUpdate Article
ボタンを押すと更新されます。
別ユーザーが編集した内容を表示してあげると、より便利になりそうです。