2012-07-07 147 views
0

如何编写Ruby on Rails迁移以生成日历表,其中所有日期都在2010年1月至2099年12月之间?Rails迁移以生成日历表

+0

(1)你尝试过什么? (2)你确定你需要一个日历表吗?有些数据库(如PostgreSQL)有更好的方法。 – 2012-07-07 21:00:17

+0

我正在使用PostgreSQL。什么是更好的方法来实现这一目标? – Myxtic 2012-07-07 21:24:28

+2

['generate_series'](http://www.postgresql.org/docs/current/static/functions-srf.html) – 2012-07-07 21:29:33

回答

1

我不明白你是什么高达,但如果你想填充从2010年1月的日期到2099年12月与迁移表,

你可以用一些东西一样

class CreateCalendar < ActiveRecord::Migration 
    def change 
    create_table :calendars do |t| 
     t.date :date 
     t.timestamps 
    end 
    end 
    (Date.new(2010,1,1)..Date.new(2099,12,31)).each do |date| 
    Calender.create(:date=> date) 
    end 
end 
+0

我的主要问题是:[http://stackoverflow.com/q/11318792/1048331],我试图通过一个日历表来解决它。 – Myxtic 2012-07-07 21:50:33

+0

在接受您的答案之前,我会等一会儿,以防您有更好的方法来解决我的问题。谢谢。 – Myxtic 2012-07-07 21:57:21

+0

@Myxtic,我试图解决你的原始问题,检查是否适合你。也让我知道你的看法。 – PriteshJ 2012-07-08 01:23:38

1

当我再次发现这个问题时,请自己参考。

模式:

create_table :calendar_days, id: false do |t| 
    t.date :day, null: false 
    t.integer :year, null: false 
    t.integer :month, null: false 
    t.integer :day_of_month, null: false 
    t.integer :day_of_week, null: false 
    t.integer :quarter, null: false 
    t.boolean :business_day, null: false 
    t.boolean :week_day, null: false 
end 

execute "ALTER TABLE calendar_days ADD PRIMARY KEY (day)" 

class CalendarDay < ActiveRecord::Base 
    self.primary_key = :day 
end 

数据:

# Non-exhaustive, needs to be customized for your needs. 
def business_day?(d) 
    matches = ->(month, day) { [month, day] == [d.month, d.day] } 
    falls_on = ->(month, wday, r) { 
    [month, wday] == [d.month, d.wday] && r.cover?(d.day) 
    } 

    return false if [0,6].include?(d.wday) # Weekends 
    return false if matches[1, 1] # New Years 
    return false if matches[7, 4] # Independence Day 
    return false if matches[12, 25] # Christmas 
    return false if matches[11, 11] # Veterans Day 
    return false if falls_on[1, 1, 15..21] # MLK Day 
    return false if falls_on[5, 1, 25..31] # Memorial Day 
    return false if falls_on[9, 1, 1..7] # Labor Day 
    return false if falls_on[11, 4, 22..28] # Thanksgiving 
    true 
end 

task populate_calendar_days: :environment do 
(Date.new(2013,1,1)...Date.new(2014,1,1)).each do |d| 
    day = CalendarDay.new(
    year:   d.year, 
    month:  d.month, 
    day_of_month: d.day, 
    day_of_week: d.wday, 
    quarter:  (d.month/4) + 1, 
    week_day:  ![0,6].include?(d.wday), 
    business_day: business_day?(d) 
) 
    day.day = d 
    day.save! 
end 
+0

感谢分享!真的很有帮助 – 2015-05-18 13:19:40