我有一个执行此操作的功能:
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
那告诉我
#p>#的未定义方法`blank_to_negative'
无论如何,我读过you're "never" supposed to do that kind of thing,所以我有点困惑。
答案 0 :(得分:3)
如果您希望在项目的每个类中都有这样的帮助方法,那么您可以将其作为方法添加到Object
或任何您认为合适的方法中> p>
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
答案 1 :(得分:2)
有几个选择:
将方法修补到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
答案 2 :(得分:1)
可以扩展Ruby数据类型功能。它们没有密封。由于您希望在所有地方使用它,为什么不扩展FIXNUM
功能并向其添加方法blank_to_negative
。
答案 3 :(得分: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_negative
重命名为negative_if_not_numeric
,因为some_string.negative_if_not_numeric
比some_string.blank_to_negative
更有意义。