在Rails 4中使用SimpleDelegator时未定义的方法m

时间:2015-01-06 17:07:20

标签: ruby-on-rails

我用原来的答案咆哮着错误的树 - 我仍然有问题,但情节变粗

我将Ruby 1.8.7 / Rails 3.0.20项目升级到Ruby 2.1.2 / Rails 4.1.8

在代码中,我有一个委托了许多实例方法的类。

class Account < ActiveRecord::Base

  has_one :subscription
  delegate :trial?, :payg? :to => :subscription

end

我有一个装饰师

class AccountOverview < SimpleDelegator
def self.for(account)
  new(account)
end

def description
  if payg?
    'Pay As You Go'
  elsif trial?
    'Free Trial'
  else
    'Subscription'
  end
end
end

从视图中访问装饰器会显示错误消息:

ActionView :: Template :: Error(未定义的局部变量或方法`m&#39; for):

我寻找一个外来的m,但找不到一个。

我原以为它使用装饰器确定没有包含委托方法的方法,并且通过在类中定义委托函数来阻止错误:

def payg?
  subscription.payg?
end

def trial?
  subscription.trial?
end

但事实并非如此。我所看到的是第二次尝试渲染视图成功。但是,如果我重新启动服务器,我会再次收到错误。

我已尝试按照建议实例化SimpleDelegator,而不是从中派生,并发现我无法访问原始类中的方法。

在rails控制台中尝试:

class Test1
  def testing
    puts 'hi'
  end
end

class Test2
  def initialize(test)
    SimpleDelegator.new(test)
    end
  def testing2
    puts 'hello'
  end
end

t = Test1.new
t.testing
hi
  => nil 

h = SimpleDelegator.new(t)

h.testing
hi
  => nil 

h = Test2.new(t)
h.testing
NoMethodError: undefined method `testing' for #<Test2:0x007fbea15d27a0>

但如果我使用

2.1.2 :008 >  class Test2 < SimpleDelegator
2.1.2 :009?>   def testing2
2.1.2 :010?>     puts 'hello'
2.1.2 :011?>     end
2.1.2 :012?>   end
 => :testing2 
2.1.2 :013 > h = Test2.new(t)
 => #<Test1:0x007fee090afc90> 
2.1.2 :014 > h.testing
hi
 => nil 
2.1.2 :015 > h.testing2
hello
 => nil 

另外,我发现在视图中渲染失败的代码在控制台中工作(从SimpleDelegator派生):

a = Account.last

c = AccountOverview.new(a)

c.description
 => "Free Trial" 

将课程简化为最简单的

class AccountOverview < SimpleDelegator
def self.for(account)
  new(account)
end

def description
    'Pay As You Go'
end


class Account < ActiveRecord::Base

end

仍然看到相同的错误,指的是缺少方法m

创建了一个全新的rails 4项目,并添加了相同的代码并针对相同的数据库运行 - 这没有任何错误,所以它在我的遗留设置中。

放弃并从代码中删除了SimpleDelegator,并使用委托将所需的函数映射到基础对象的实例变量,并且它现在正在工作。但不是很满意。

class AccountOverview

  delegate :payg?, :trial? :to => :@account

  def initialize(account)
    @account = account
  end

  def description
    if payg?
      'Pay As You Go'
    elsif trial?
      'Free Trial'
    else
      'Subscription'
    end
  end
end

0 个答案:

没有答案