use*_*689 3 ruby ruby-on-rails redmine redmine-plugins ruby-on-rails-3
我在编写Redmine插件时遇到验证问题.
我正在为问题模型编写一个钩子,作为钩子方法的一部分,我想通过添加自定义错误来使问题的创建无效:
def controller_issues_new_before_save( context = { } )
context[:issue].errors.add(:due_date, "A custom error")
end
Run Code Online (Sandbox Code Playgroud)
出于测试目的,我编写了一个覆盖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
Run Code Online (Sandbox Code Playgroud)
其中Issue.can_validate是Issue模型的补充
但是,这似乎不是最好的方法.有没有更简单的方法?
如果您想要验证数据,您应该直接修补模型而不是使用钩子.钩子用于将HTML插入页面或更改控制器的控制流.使用钩子也意味着您的代码只适用于通过应用程序的那条路径,因此如果有人在其他地方创建了问题,那么您的代码将无法运行.
要创建补丁,您只需要做两件事:
我在插件中做了这个确切的事情,在一个问题上添加了一个验证,要求在将来设置到期日期.它的补丁很简单,所以我将它包含在这里:
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
Run Code Online (Sandbox Code Playgroud)
在class_eval里面你可以放置自己的代码,我建议使用与validate_on_create不同的名称.否则,如果他们想要使用该方法,则可能会遇到其他代码的问题.
第二部分(包括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
Run Code Online (Sandbox Code Playgroud)
您需要将它包装在Dispatcher中以使开发模式下的工作正常.我在博客上写过这篇文章.
随意从github复制我的插件来进行更改,这很简单.https://github.com/edavis10/redmine_require_issue_due_date_in_future
| 归档时间: |
|
| 查看次数: |
1977 次 |
| 最近记录: |