質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

482閲覧

ユーザに改変されると困るパラメータの更新における、セキュリティ担保の方法について

Nicole_

総合スコア14

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2020/02/15 14:35

編集2020/02/17 05:10

ある処理の状態を変える方法のベストプラクティスを教えてください。

例)
申請書類の状態を3つのステータス({ 1:未確認, 2:確認待ち, 3:確認済み})で管理しているとします。
それぞれ【申請テーブル】【ステータステーブル】を持ち、申請テーブルはステータスIDを外部キーとしてステータステーブルとアソシエーションしている状態です。

ルールとして、未確認→確認済みにはできず、必ず(未確認⇄確認待ち⇄確認済み)というフローで切り替えが行われます。

これらステータスを切り替える時は、申請#editでhiddenでステータスIDを送ることを考えたのですが、これだとソース上で書き換えられてしまう(1 → 3にされて未確認→確認済み等)可能性があるため、セキュリティ上よくないと思い、他の方法を考えていたのですが、なかなか思いつかず...
※editで、変更できるのはステータスIDだけです。

調べたところ、

・modelでフィルターに引っ掛けてupdate_culumなどを使い書き換える
・controllerでparamの値を加工する

などが載っていました。
他にもあるのであれば、知っておきたいので教えていただければと思います。
よろしくお願いします。

そもそも、editに

<%= form_for(@hoge, url: huga_path) do |f| %>  <%= f.hidden_field :status_id, :value => 2 %>  <%= f.submit "状態を変更する" %> <% end %>

のように、「ステータス」を変えるだけの極小のformをおくこと自体ナンセンスなのでしょうか...?

ちなみに、申請の作成(create)時は、modelでafter_saveでself.ステータスIDに値がなければ、”1”を入れる。というような処理にしています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2020/02/15 15:51 編集

業務フローについて質問です。ステータスを変更できるユーザー(特に確認済み)の制約とかはないのでしょうか?
Nicole_

2020/02/16 05:59

ご覧いただきありがとうございます! ユーザ自体も一般ユーザと管理者とわかれており、確認待ち⇄確認済みは管理者のみ管理画面で行えるようになっています。 管理画面へのアクセス制限はできているので、一般ユーザが入ることはできません。
guest

回答2

0

ベストアンサー

modelレベルではこちらで制御するのがデファクトスタンダードです。
https://github.com/aasm/aasm

投稿2020/02/15 16:04

matsubokkuri

総合スコア744

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nicole_

2020/02/17 05:02

回答ありがとうございます! こんな便利なgemがあったとは...(他にもステート管理系のgemはあるみたいなので、機会があれば使ってみます) 今回はこちらで実装したので、ベストアンサーとさせていただきます。 追加で質問というか、なんで?ってなった部分として、追記しておきますので、よかったらこちらも確認していただけると助かります。
guest

0

この前作った(そして、やっと先週末から稼働できるようになった)メール配信プログラムで似たような事をしました。メールについて、利用者が「新規作成」後に「申請」し、管理者が「承認」するとメールが配信されるという仕組みで、状態も「下書き」->「保留中」->「配信待ち」(ジョブに入っていて、配信されると「配信済み」になる)という感じで遷移するというものです。他にも状態(「配信失敗」とか)があって、それぞれ権限や移れる状態が異なるため、結構複雑な処理が必要でした。

そこで、アクセス管理にpunditを採用し、アクションを制限することで許可なき遷移が行われないようにしました。punditはポリシーベースのアクセス管理で、ユーザーとレコードの状態を組み合わせて、アクションに対する制限が掛けられます。状態を変更する処理はそれぞれ別アクションにしました。「申請」ボタンを押すと「申請」のアクションが呼び出され、状態が「下書き」から「保留中」に変わるという感じです。そして「承認」自体ができるかどうかをpunditでユーザー(メールの作成者かどうか)とメールの状態(「下書き」かどうか)から可否を判定するというものです。画面側でも、この可否を使って、ボタンを表示する・しないをわけています。

Hogeモデルに対して「未確認(unverified)」から「確認待ち(pending_verification)」にする「申請(apply)」を設定するのであれば、次のような感じになるでしょう。(実際に下のコードを試したわけではありませんので、詳しい使い方は各マニュアルを参考にしてください。)

config/routes.rb

Ruby

1Rails.application.routes.draw do 2 resources :hoge do 3 member do 4 put'apply' 5 end 6 end 7end

app/policies/hoge_policy.rb

Ruby

1class HogePolicy < ApplicationPolicy 2 def apply? 3 record.status.name == 'unverified' 4 end 5end

app/controllers/hoges_controller.rb

class HogesController < ApplicationController before_action :set_hoge, only: [:show, :edit, :update, :destroy, :apply, ...] def apply @hoge.update(status: Status.find_by_name('pending_verification')) # その他必要な処理をしていく… end def set_hoge @hoge = Hoge.find(params[:id]) authorize @hoge end end

app/views/hoges/show.html.erb

ERB

1<% if policy(@hoge).apply? %> 2 <%= form_for(@hoge, url: apply_hoge_path(@hoge), method: :put) do |f| %> 3 ... 4 <%= f.submit '申請' %> 5 <% end %> 6<% end %>

なお、アクションを介さなかった場合、つまり、コンソールで直接モデルを操作した場合等は制限されません。punditによる制限の範囲外だからです。イレギュラーな事態が発生したとき、DB直接ではなくコンソールからモデルを操作できるようにするため、そのような制限は設けませんでした。

これがベストプラクティスなのかと言われると私にはわかりません。最初はアクションをわけない方法を考えていたのですが、punditでポリシー管理するならわけた方が書きやすいと言うことに気付いて、このようになりました。まだ、稼働して一週間ぐらいで、4月の本運用に向けて試験運用中のものですのですし、もしかしたら、大きな問題があるかも知れません。作ったものは組織内で使うWebアプリであるため、売り物として耐えられる設計なのかは不明です。

投稿2020/02/15 16:16

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nicole_

2020/02/17 05:07

回答いただきありがとうございます! ポリシーで管理するという方法もまたいいかなと思いましたが、 今回の解決したいことは、アカウントごとのアクション管理より、ステータス管理の方が適していると思い他の方の方法を採用させていただきました。 raccyさんがあげていただいた方法は、また別の機会に実装してみたいと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問