- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
在 state_machine 中的转换之前执行验证的正确语法是什么? gem ?
我试过以下,
before_transition :apple => :orange do
validate :validate_core
end
def validate_core
if core.things.blank?
errors.add(:core, 'must have one thing')
end
end
但是我得到以下错误,
undefined method `validate' for #<StateMachine::Machine:0x007ffed73e0bd8>
我也试过把它写成,
state :orange do
validate :validate_core
end
但这会导致记录保存后回滚,不太理想。我想首先阻止状态机转换为 :orange
。
核心问题是,在我的 Controller 中,我的逻辑依赖于 object.save
的结果。我对状态机的验证直到初始保存后才会启动,因此保存返回为 true,并且 Controller 继续逻辑,如果对象无效,它不应该命中。
除了检查保存之外,我还通过手动测试有效性来解决这个问题,但感觉应该有一种方法可以在对象保存之前触发验证。
最佳答案
该特定状态机的想法是将验证声明嵌入到状态中。
state :orange do
validate :validate_core
end
上面的配置将在对象转换为橙色时执行验证 :validate_core
。
event :orangify do
transition all => :orange
end
我理解您对回滚的担忧,但请记住,回滚是在事务中执行的,因此成本非常低。
record.orangify!
此外,请记住您还可以使用不使用异常的非 bang 版本。
> c.orangify
(0.3ms) BEGIN
(0.3ms) ROLLBACK
=> false
也就是说,如果您想使用基于转换前的不同方法,那么您只需要知道如果回调返回 false,转换就会停止。
before_transition do
false
end
> c.orangify!
(0.2ms) BEGIN
(0.2ms) ROLLBACK
StateMachine::InvalidTransition: Cannot transition state via :cancel from :purchased (Reason(s): Transition halted)
请注意,事务始终会启动,但如果回调在最开始时可能不会执行任何查询。
before_transaction
接受一些参数。您可以生成对象和事务实例。
before_transition do |object, transaction|
object.validate_core
end
事实上你可以通过事件来限制它
before_transition all => :orange do |object, transaction|
object.validate_core # => false
end
在这种情况下,validate_core
应该是一个返回 true/false 的简单方法。如果您想使用定义的验证链,那么我想到的是在模型本身上调用 valid?
。
before_transition all => :orange do |object, transaction|
object.valid?
end
但是请注意,您不能在事务范围之外运行事务。事实上,如果您检查 perform
的代码,您会发现回调在事务中。
# Runs each of the collection's transitions in parallel.
#
# All transitions will run through the following steps:
# 1. Before callbacks
# 2. Persist state
# 3. Invoke action
# 4. After callbacks (if configured)
# 5. Rollback (if action is unsuccessful)
#
# If a block is passed to this method, that block will be called instead
# of invoking each transition's action.
def perform(&block)
reset
if valid?
if use_event_attributes? && !block_given?
each do |transition|
transition.transient = true
transition.machine.write(object, :event_transition, transition)
end
run_actions
else
within_transaction do
catch(:halt) { run_callbacks(&block) }
rollback unless success?
end
end
end
# ...
end
要跳过事务,您应该猴子修补 state_machine,以便转换方法(例如 orangify!
)在转换之前检查记录是否有效。
这是你应该达到的目标的例子
# Override orangify! state machine action
# If the record is valid, then perform the actual transition,
# otherwise return early.
def orangify!(*args)
return false unless self.valid?
super
end
当然,您不能为每个方法手动执行此操作,这就是为什么您应该猴子修补库以实现此结果的原因。
关于ruby-on-rails - 在 state_machine gem 上持久化之前的验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20157664/
使用 state_machine gem,我希望验证只在转换上运行。例如: # Configured elsewhere: # StateMachine::Callback.bind_to_objec
我似乎无法获得 state_machine gem ( http://github.com/pluginaweek/state_machine/ ) 来处理现有记录(它可以在新记录上正常工作)。 这是
我使用 state_machine在我的 Rails 3.1 应用程序之一上使用 ActiveRecord。我发现访问具有不同状态的记录的语法很麻烦。是否可以将每个状态同时定义为作用域而不用手写作用域
我正在尝试将一些重复的逻辑分解为 concern .部分重复的逻辑是 state_machine . 简化后,Database , Site , SftpUser以及更多包含,其中包括: class
请帮我。我很困惑。我知道如何编写模型的状态驱动行为,但我不知道我应该在规范中写什么...... 我的model.rb文件看看 class Ratification :boss do stat
我们在项目中使用 state_machine ( https://github.com/pluginaweek/state_machine ),并希望提供一个带有选择的表单,让我们选择一个状态。 (这
我有一个参与者模型,带有 state_machine last_action。我想根据角色属性设置last_action 的初始值。如果角色为“导师”,则初始值为“值1”,而如果角色为“学生”,则初始
在 Rails 3.2 应用程序上 gem 文件: gem "state_machine", "~> 1.1.2" gem 'ruby-graphviz', :require => 'graphviz
是否可以从模型类中获取所有事件?我想按事件过滤列表。 有一个 similar question on mailinglist关于所有的过渡。 我正在使用 https://github.com/plug
我正在使用 https://github.com/pluginaweek/state_machine 我的代码是 event :set_running do transition any => :r
我正在使用 state_machine构建一个多步骤表单,在过渡到下一步之前验证每个步骤的字段。 这是我的模型: class Foo :step1 do event :next do
我正在使用 https://github.com/state-machines/state_machines用于 Rails 在对象状态更改前后存储和执行工作。 我想做的是拥有一个可以在 before
我在我的一个模型中使用 state_machine 进行状态转换。过渡在单个记录上成功发生。但是如果我必须在多个记录上触发一个事件怎么办。我可以使用 在多个记录中进行转换 @records.
我正在使用 boost::state_chart 库。出于调试目的,我想随时了解状态机的状态。如何获取 state_machine 对象中的当前(最派生的)状态? 最佳答案 您可以使用 state_m
我正在使用 boost::statechart::state_machine 并且我遇到了机器崩溃。在对核心进行调查后,我意识到这是因为多个线程几乎同时处理了一个事件,其中一个线程称为终止,另一个线程
我有一个依赖 state_machine 来管理其不同状态的模型。一个特定的事件需要一个 before_transition,因为它需要在进行转换之前构建一个连接表。不幸的是,它不起作用。 class
我正在使用 state_machine gem 来模拟纸牌游戏,我有一个转换条件,需要在绘制纸牌时知道事件参数。这是一些示例代码。 class CardGame state_machine do
我正在使用 state_machine on rails 开发状态机,这里我定义了不同的状态,根据条件状态将更改为另一个状态。这里我的问题是如何获得以前的状态?我的第二个问题是如何列出状态机中的所有状
我使用 gem state_machine - Official 每个州都可以有“人名”。通过我尝试过的文档和 API: 在 my_model.rb 中 state_machine :initial
在 state_machine 中的转换之前执行验证的正确语法是什么? gem ? 我试过以下, before_transition :apple => :orange do validate :
我是一名优秀的程序员,十分优秀!