Ruby on Railsで今の季節が分かるライブラリ的なのが無かったので、ActiveModelでクラスを作ってみたよ
RubyのDateやTimeのライブラリは、とても使いやすくて素晴らしいのだけど、今の季節が一瞬でわかるライブラリや、Dateクラスにもそんなメソッドが無かった気がするので、
簡単に実装してみたよ。
@season = Season.new # => #<Season:0x00000104f4c298 @from=Wed, 01 Oct 2014, @to=Wed, 31 Dec 2014, @from_to=Wed, 01 Oct 2014..Wed, 31 Dec 2014, @name="秋", @code=:autumn>
↑こんなコードで、今日がどの季節なのかが分かるインスタンスが得られるように
ActiveModelを使ってクラスを作ってみたよ。
※IDEで書いたコードをそのままペタ張りしてるので、インデントがアレで見づらいです。
class Season include ActiveModel::Model @@seasons = {winter: "冬", spring: "春", summer: "夏", autumn: "秋"} attr_accessor :from attr_accessor :to attr_accessor :from_to attr_accessor :name attr_accessor :code def initialize opt={} super now_season = self.class.now_season(opt[:code]) self.from = now_season[:from] self.to = now_season[:to] self.from_to = now_season[:from_to] self.name = now_season[:name] self.code = opt[:code] || now_season[:code] end @@seasons.keys.each {|code| define_method("#{code}?"){ self.code == code } } class << self @@seasons.each { |code, name| define_method("#{code}_attributes") { from, to = eval(code.to_s) {from: from, to: to, from_to: from..to, name: name, code: code} } } def winter? season?(winter) end def spring? season?(spring) end def summer? season?(summer) end def autumn? season?(autumn) end def season?(from_to) from_to = from_to[0]..from_to[1] from_to.include?(Date.today) end def winter season_from_to("01-01","03-31") end def spring season_from_to("04-01","06-30") end def summer season_from_to("07-01","09-30") end def autumn season_from_to("10-01","12-31") end def season_from_to(from,to) today = Date.today from = "#{today.year}-#{from}".to_date to = "#{today.year}-#{to}".to_date return from, to end def now_season (code = nil) if code return eval("#{code}_attributes") end attr = case when winter? then winter_attributes when spring? then spring_attributes when summer? then summer_attributes when autumn? then autumn_attributes end; attr end end end
生成したインスタンスで
season = Season.new #=> #<Season @from=Wed, 01 Oct 2014, @to=Wed, 31 Dec 2014, @from_to=Wed, 01 Oct 2014..Wed, 31 Dec 2014, @name="秋", @code=:autumn> season.autumn? # => true season.winter? # => false season.from_to # => Wed, 01 Oct 2014..Wed, 31 Dec 2014
として、今の季節を調べたり
season = Season.new(code: :summer) # => #<Season:0x00000104f479a0 @from=Tue, 01 Jul 2014, @to=Tue, 30 Sep 2014, @from_to=Tue, 01 Jul 2014..Tue, 30 Sep 2014, @name="夏", @code=:summer>
などとして、明示的に季節を指定してインスタンスを生成したり出来るようにしたよ。
Rails 4のActiveModelというAPIがとても便利で、DBに関係ないモデルをActiveRecordのように使えるようになるよ。
ActiveModelの練習で今の季節が分かるSeasonクラスを作ってみて楽しかったけど、
あんまり使いところがなさそうだね!!
...。