Rails迁移:检查是否存在多个列

时间:2019-03-22 14:13:38

标签: ruby-on-rails ruby database migration

我有一个公司表,我想检查是否存在多个列以将其删除。

class RemoveSettingsReportColumnsFromCompany < ActiveRecord::Migration[5.1]
  def change
    if column_exists?( :companies, :automatically_send_report ) && column_exists?( :companies, :time_limit_for_sending_report ) && column_exists?( :companies, :report_fragment_color ) && column_exists?( :companies, :display_default_avatar )
      remove_column :companies, :automatically_send_report, :boolean
      remove_column :companies, :time_limit_for_sending_report, :integer
      remove_column :companies, :report_fragment_color, :string
      remove_column :companies, :display_default_avatar, :boolean
    end
  end
end

如您所见,使用功能 column_exists 有很多重复,我想更好地组织和减少代码,有人可以告诉我们是否有一种使用 column_exists的方法,然后将我要删除的所有列都作为参数提供?

2 个答案:

答案 0 :(得分:0)

可以稍微简化一下。首先-您可以使用Company.attribute_names列出所有属性。它将返回一个数组。因此,您可以执行以下操作:

if (%w[automatically_send_report time_limit_for_sending_report report_fragment_color display_default_avatar] - Company.attribute_names).empty?
  # migration code
end

另一种解决方案,更漂亮(IMO):

if Company.attribute_names.to_set.superset?(Set['automatically_send_report', 'time_limit_for_sending_report', 'report_fragment_color', 'display_default_avatar'])
  # migration code
end

答案 1 :(得分:0)

FIELDS = %i[automatically_send_report time_limit_for_sending_report
            report_fragment_color display_default_avatar].zip(
         %i[boolean integer string boolean]).to_h

def up
  FIELDS.keys.each do |col|
    remove_column(:companies, col) if column_exists?(:companies, col)
  end
end

def down
  FIELDS.each do |col, type|
    add_column(:companies, col, type) unless column_exists?(:companies, col)
  end
end