2012-05-03 18 views
1

我必須在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

Yossi&xzgyb謝謝。我希望我能接受這兩個答案。我跟Yoss一起去了,因爲這是我實際執行的那個。 – Ethan

回答

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 
+0

非常好。我喜歡。 – Ethan

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 
+0

很Rubyish。大。 – Ethan