我必须在ActiveRecord模型上实现这些方法,以支持一些所需的视图功能。
我认为必须有一种更紧凑的方式来声明这些方法,可能涉及符号数组和Array#each
调用。
有什么建议吗?
(这些是旧版列名,BTW。)
class Contract < ActiveRecord::Base
def start_date_displayed
self.start_date.present? ? self.start_date.strftime("%-m/%-d/%Y") : ''
end
def start_date_displayed=(input)
if input.present?
self.start_date = Date.strptime input, '%m/%d/%Y'
end
end
def end_date_displayed
self.end_date.present? ? self.end_date.strftime("%-m/%-d/%Y") : ''
end
def end_date_displayed=(input)
if input.present?
self.end_date = Date.strptime input, '%m/%d/%Y'
end
end
def ArrivalDate_displayed
self.ArrivalDate.present? ? self.ArrivalDate.strftime("%-m/%-d/%Y") : ''
end
def ArrivalDate_displayed=(input)
if input.present?
self.ArrivalDate = Date.strptime input, '%m/%d/%Y'
end
end
def Contract_ReceivedDate_displayed
self.Contract_ReceivedDate.present? ? self.Contract_ReceivedDate.strftime("%-m/%-d/%Y") : ''
end
def Contract_ReceivedDate_displayed=(input)
if input.present?
self.Contract_ReceivedDate = Date.strptime input, '%m/%d/%Y'
end
end
def Contract_FinalizedDate_displayed
self.Contract_FinalizedDate.present? ? self.Contract_FinalizedDate.strftime("%-m/%-d/%Y") : ''
end
def Contract_FinalizedDate_displayed=(input)
if input.present?
self.Contract_FinalizedDate = Date.strptime input, '%m/%d/%Y'
end
end
def Committee_Date_displayed
self.Committee_Date.present? ? self.Committee_Date.strftime("%-m/%-d/%Y") : ''
end
def Committee_Date_displayed=(input)
if input.present?
self.Committee_Date = Date.strptime input, '%m/%d/%Y'
end
end
# ...
end
答案 0 :(得分:2)
class Contract < ActiveRecord::Base
%w(start_date end_date).each do |attr_name|
class_eval <<-METHOD_DEF
def #{attr_name}_displayed
self.#{attr_name}.present? ? self.#{attr_name}.strftime("%-m/%-d/%Y") : ''
end
def #{attr_name)_displayed=(input)
if input.present?
self.#{attr_name} = Date.strptime #{attr_name}, '%m/%d/%Y'
end
end
METHOD_DEF
end
end
如果只为那些名称以日期结尾的列定义这些方法,那么
class Contract < ActiveRecord::Base
self.column_names.grep(/date$/i).each do |column_name|
class_eval <<-METHOD_DEF
def #{column_name}_displayed
self.#{column_name}.present? ? self.#{column_name}.strftime("%-m/%-d/%Y") : ''
end
def #{column_name)_displayed=(input)
if input.present?
self.#{column_name} = Date.strptime #{column_name}, '%m/%d/%Y'
end
end
METHOD_DEF
end
end
答案 1 :(得分:1)
尽可能避免简单的逃避。
class Contract < ActiveRecord::Base
class << self
def attr_displayed *attrs
attrs.each do |attr|
displayed = :"#{attr}_displayed"
define_method displayed do
send(attr).present? ? send(attr).strftime("%-m/%-d/%Y") : ''
end
define_method :"#{displayed}=" do |input|
if input.present?
send :"#{attr}=", Date.strptime(input, '%m/%d/%Y')
end
end
end
end
end
attr_displayed :start_date, :end_date, :ArrivalDate, :Committee_Date,
:Contract_ReceivedDate, :Contract_FinalizedDate
end