【问题标题】:Rails Migration to Generate a Calendar TableRails 迁移以生成日历表
【发布时间】:2012-07-07 20:48:54
【问题描述】:

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

【问题讨论】:

  • (1) 你试过什么? (2) 你确定你需要一个日历表吗?一些数据库(如 PostgreSQL)有更好的方法。
  • 我正在使用 PostgreSQL。实现这一目标的更好方法是什么?
  • 如果我理解得很好,generate_series 的问题是需要为每个连续的查询生成它,并且根据序列的长度,可能需要几毫秒。

标签: ruby-on-rails database activerecord rails-migrations


【解决方案1】:

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

架构:

create_table :calendar_days, primary_key: :day, id: :date do |t|
  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

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|
    CalendarDay.create!(
      day:          d,
      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)
    )
  end
end

【讨论】:

    【解决方案2】:

    我不明白你在做什么,但如果你想在表格中填充从 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
    

    【讨论】:

    • 我的主要问题是:[stackoverflow.com/q/11318792/1048331],我正试图通过一个日历表来解决它。
    • 我会稍等片刻接受你的回答,以防你有更好的方法来解决我的问题。谢谢。
    • @Myxtic,我已尝试解决您的原始问题,检查是否适合您。也让我知道你对它的看法。
    • 我还没有尝试过你对我原来问题的解决方案,但你对我的问题的回答肯定有效。谢谢。
    猜你喜欢
    • 2013-02-16
    • 2016-08-02
    • 2011-07-27
    • 1970-01-01
    • 2013-12-14
    • 2015-12-07
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    相关资源
    最近更新 更多