4

我有一个功能可以做到这一点:

  def blank_to_negative(value)
    value.is_number? ? value : -1
  end

如果传递的值不是数字,则将值转换为 -1。

我主要为某个模型创建了这个函数,但是在任何一个模型中定义这个函数似乎都不合适,因为这个函数的应用范围显然可以超出任何一个特定的模型。我几乎可以肯定在其他模型中需要这个功能,并且可能在视图中。

定义此功能然后在任何地方使用它的最“Rails Way”方式是什么,尤其是在模型中?

我试图在 中定义它ApplicationHelper,但它不起作用:

class UserSkill < ActiveRecord::Base
  include ApplicationHelper
  belongs_to :user
  belongs_to :skill

  def self.splice_levels(current_proficiency_levels, interest_levels)
    Skill.all.reject { |skill| !current_proficiency_levels[skill.id.to_s].is_number? and !interest_levels[skill.id.to_s].is_number? }.collect { |skill| {
      :skill_id => skill.id,
      :current_proficiency_level => blank_to_negative(current_proficiency_levels[skill.id.to_s]),
      :interest_level => blank_to_negative(interest_levels[skill.id.to_s]) }}
  end 
end

那告诉我

未定义的方法 `blank_to_negative' 用于#

无论如何,我读到你“永远”不应该做那种事情,所以我有点困惑。

4

4 回答 4

3

如果您想在项目中的每个类中都有这样的辅助方法,那么您可以自由地将其添加为方法Object或任何您认为合适的方法:

module MyApp
  module CoreExtensions
    module Object
      def blank_to_negative
        self.is_number? ? self : -1
      end
    end
  end
end

Object.send :include, MyApp::CoreExtensions::Object
于 2012-08-07T19:47:04.387 回答
2

有几个选项:

  • Monkey-patch 该方法到 ActiveRecord 中,它将在您的所有模型中可用:

    class ActiveRecord::Base
      def blank_to_negative(value)
        value.is_number? ? value : -1
      end
    end
    
  • 添加一个“关注”模块,然后将其混合到选定的模型中:

    # app/concerns/blank_to_negate.rb
    module BlankToNegate
      def blank_to_negative(value)
        value.is_number? ? value : -1
      end
    end
    
    # app/models/user_skill.rb
    class UserSkill < ActiveRecord::Base
      include BlankToNegate
      # ...
    end
    
于 2012-08-07T19:46:45.603 回答
1

Ruby 数据类型功能可以扩展。它们没有密封。既然您想在所有地方使用它,为什么不扩展FIXNUM功能并blank_to_negative为其添加方法。

于 2012-08-07T19:58:50.223 回答
0

这就是我最终做的事情。我把这段代码放在config/initializers/string_extensions.rb.

class String
  def is_number?
    true if Float(self) rescue false
  end 

  def negative_if_not_numeric
    self.is_number? ? self : -1
  end 
end

另外,我重命名blank_to_negativenegative_if_not_numeric, 因为some_string.negative_if_not_numericsome_string.blank_to_negative.

于 2012-08-08T14:30:06.483 回答