3

Redmine プラグインの作成時に検証の問題が発生しています。

問題モデルのフックを作成しています。フック メソッドの一部として、カスタム エラーを追加して、問題の作成を無効にしたいと考えています。

  def controller_issues_new_before_save( context = { } )
     context[:issue].errors.add(:due_date, "A custom error")
  end

テスト目的で、Issue.validate_on_create を上書きするパッチを作成しましたが、validate_on_create を入力するたびに errors.count がゼロに設定されているようです。

課題オブジェクトの作成を停止する必要がありますが、属性が別のモデル オブジェクトに設定されている場合のみです。

これをvalidate_on_createメソッドに書こうと思ったのですが、そうすると他のオブジェクトに渡す必要があります。

私が考えた最初の解決策は、Issue モデルに追加のフィールドを挿入し、それをフック内で変更することです。

何かのようなもの :

  def controller_issues_new_before_save( context = { } )
    context[:issue].can_validate = false
  end

  def validate_on_create
    unless can_validate 
      errors.add("error", "A custom error")
    end
  end   

ここで、Issue.can_validate は Issue モデルへの追加です

ただし、これはここでの最良のアプローチではないようです。もっと簡単な方法はありますか?

4

2 に答える 2

5

データを検証したい場合は、モデルに直接パッチを適用し、フックを使用しないでください。フックは、HTML をページに挿入したり、コントローラーの制御フローを変更したりするために使用することを意図しています。フックを使用するということは、コードがアプリケーション内のその 1 つのパスに対してのみ機能することも意味します。そのため、誰かが別の場所で問題を作成した場合、コードは実行されません。

パッチを作成するには、次の 2 つのことを行うだけです。

  1. コードを含むモジュールを作成する
  2. Redmine にそのモジュールを Issue クラスに含めさせます。

私はこれとまったく同じことをプラグインで行いました。プラグインは課題に検証を追加して、期日が将来設定されることを要求します。パッチはかなり単純なので、ここに含めます。

module RedmineRequireIssueDueDateInFuture
  module Patches
    module IssuePatch
      def self.included(base)
        base.class_eval do
          unloadable

          validate :due_date_in_future

          protected
          def due_date_in_future
            return true if due_date.nil?

            if due_date.to_time < Date.today.beginning_of_day
              errors.add :due_date, :not_in_future
            end

          end

        end
      end
    end
  end
end

class_eval の内部は、独自のコードを配置する場所です。validate_on_create とは別の名前を使用することをお勧めします。そうしないと、他のコードでもそのメソッドを使用したい場合に問題が発生する可能性があります。

2 番目の部分 (Redmine へのモジュールを含む) はかなり簡単です。Issue クラスを必要とし、include を使用してそれをクラスに追加するだけです。

# init.rb
require 'dispatcher'
Dispatcher.to_prepare :redmine_require_issue_due_date_in_future do
  require_dependency 'issue'
  Issue.send(:include, RedmineRequireIssueDueDateInFuture::Patches::IssuePatch)
end

開発モードで作業を続けるには、これを Dispatcher でラップする必要があります。私は自分のブログでそれについて書いています。

私のプラグインを github から自由にコピーして変更を加えてください。とても簡単です。https://github.com/edavis10/redmine_require_issue_due_date_in_future

于 2011-08-04T22:59:22.597 に答える