2016-04-01 41 views
0

Eval()用於在Rails 4.2模型payment_request中評估workflow塊。下面是使用evalworkflow塊:eval中的未定義方法()

class PaymentRequest < ActiveRecord::Base 
    include Workflow 
    def self.load_wf 
     workflow do 
     state :initial_state do 
      event :submit, :transitions_to => :ceo_reviewing 
     end 
     state :ceo_reviewing do 
      event :reject, :transitions_to => :rejected 
      event :approve, :transitions_to => :approved 
     end 
     state :rejected 
     state :approved 
     end 
    end 
    .......... 
    end 

字符串變量spec被定義爲:

spec = "state :initial_state do 
    event :submit, :transitions_to => :ceo_reviewing 
    end 
    state :ceo_reviewing do 
    event :reject, :transitions_to => :rejected 
    event :approve, :transitions_to => :approved 
    end 
    state :rejected 
    state :approved" 

和重寫:

class PaymentRequest < ActiveRecord::Base 
    include Workflow 
    def self.load_wf(spec) 
     eval("Workflow::ClassMethods.workflow {#{spec}}")  
    end 
    ............... 
    end 

eval生成錯誤:

undefined method 'workflow' for Workflow::ClassMethods:Module.

workflow是一個寶石的方法:

module Workflow 
    module ClassMethods 
    attr_reader :workflow_spec 
    ..... 
    def workflow(&specification) 
     assign_workflow Specification.new(Hash.new, &specification) 
    end 
    ...... 
    end 
end 

嘗試添加在EVAL約束力和沒有工作(不知道是否綁定正確使用)。如何使eval找到方法workflow &在模型payment_request中執行它?

回答

2

我認爲這裏的問題是,你正試圖調用一個方法,然後再正確地混合進來。模塊打算使用的方式是documented on the home page。由於您正在動態地進行此操作,因此您需要嘗試儘可能匹配它。

也就是說,做這樣的事情:

class PaymentRequest < ActiveRecord::Base 
    include Workflow 

    def self.load_wf(spec) 
    instance_eval("workflow {#{spec}}")  
    end 
end 

workflow方法應該在你這裏執行的背景下定義,作爲PaymentRequest類,並使用instance_eval可能與它設置正確的綁定。 eval可能工作,所以也試試。

+0

我接近這個問題的步驟是step1#使用普通代碼運行'load_wf'並且沒有任何'eval'。 step1工作後,step2#用'eval'代替代碼。引入'eval'後,問題發生在第2步。在第1步中,'workflow'被成功調用,並且我沒有看到mixin問題。正如你在另一篇文章中指出的那樣,我覺得它更可能是一個範圍(綁定)與'eval'。但除了一些定義之外,關於「綁定」的網絡並不多。 – user938363

+0

在發佈之前,我嘗試了'instance_eval','class_eval',它們返回相同的錯誤。 – user938363

+0

你可以做一些測試,比如'instance_eval(「raise self.methods.inspect」)'看看它是否在那裏。它應該是! – tadman