此代码适用于控制台,但不适用于迁移。为什么?

时间:2016-05-18 20:21:08

标签: ruby-on-rails

我很乐意在Rails 4.2.0控制台中执行此行:

minimumLineHeight

这两个模型有点神奇:它们都有这样的方法:

State.update_all(country_id: Country.where(iso_abbr: 'US').first_or_create(name: 'United States').id)

我在控制台中运行它没有问题。按预期工作(如果不存在则创建新的国家/地区记录,并将当前数据库中的每个州设置为国家/地区)。但情况并非在迁移中运行时。

我得到的错误告诉我该方法没有def iso_abbr=(value) super((value||'').upcase) end

  

super:没有超类方法super iso_abbr ='

我错过了什么?为什么它在控制台上运行而不在迁移?

state.rb文件:

iso_abbr=' for #<Country:0x005612cf9f8ca0>/.../country.rb:8:in

country.rb文件:

class State < ActiveRecord::Base
  validates_presence_of :iso_abbr, :name, :country, :postal_code_usage
  validates_inclusion_of :postal_code_usage, in: %w(country doesnt_use requires), if: :postal_code_usage
  validates_uniqueness_of :iso_abbr, scope: :country_id
  belongs_to :country
  has_many :counties, dependent: :destroy

  def iso_abbr=(value)
    super((value || '').upcase)
  end

  def is_fl?
    @is_fl ||= iso_abbr == "FL"
  end

  def uses_postal_code?
    case postal_code_usage.to_sym
      when :country
        country.uses_postal_code?
      when :doesnt_use
        false
      when :requires
        true
    end
  end
end

迁移代码:

class Country < ActiveRecord::Base
  validates_presence_of :iso_abbr, :name, :postal_code_usage
  validates_inclusion_of :postal_code_usage, in: %w(doesnt_use requires), if: :postal_code_usage
  validates_uniqueness_of :iso_abbr
  has_many :states, dependent: :destroy

  def iso_abbr=(value)
    super((value || '').upcase)
  end

  def uses_postal_code?
    case postal_code_usage.to_sym
      when :doesnt_use
        false
      when :requires
        true
    end
  end
end

修改:我找到了原因但不是令人满意的解决方法。 以前,同一迁移正在创建数据库中的国家/地区表。这意味着class MyMigration < ActiveRecord::Migration def change create_table :countries do |table| table.timestamps table.string :iso_abbr, unique: true table.string :name, null: false, limit: 100 table.string :postal_code_usage, null: false, limit: 10, default: :requires end change_table :states do |table| table.string :postal_code_usage, null: false, limit: 10, default: :country end # I tried here to put Country.reset_column_information but did not help. reversible do |direction| direction.up do # THIS LINE EXPLODES. State.update_all(country_id: Country.where(iso_abbr: 'US').first_or_create(name: 'United States').id) end direction.down do State.update_all(country_id: nil) end end reversible do |direction| direction.up do # Disallowing null in the column ... change_column :states, :country_id, :integer, null: false end direction.down do # Disallowing null in the column ... change_column :states, :country_id, :integer, null: true end end # Add the unique index to both fields ... add_index :states, [:iso_abbr, :country_id], unique: true create_table :addresses do |table| table.timestamps # Location Type: :regular for regular addresses, :no_number if given street + property name, # :no_street if given just property name. table.string :location_type, null: false, limit: 10 # Address Type: :individual for regular houses, :shared if in building or complex table.string :residence_type, null: false, limit: 10 # Actual address fields here (they must be unfilled or null according to `location_type`) table.references :state, null: false # IMnshO the reference should be done against :county instead of :state table.string :city, null: false, limit: 100 table.string :street, null: true, limit: 70 table.string :name, null: true, limit: 70 table.string :number, null: true, limit: 16 # Postal code will be required, or not, according to what the state tells. table.string :postal_code, null: true, limit: 16 # Extra data will be required exactly when `residence_type`==:shared and nil otherwise table.string :extra, null: true, limit: 100 end # A state in use cannot be deleted (so we avoid breaking the whole data). add_foreign_key :addresses, :states, column: :state_id change_table :clients do |table| table.references :address, null: true, default: nil end add_foreign_key :clients, :addresses, column: :address_id end end 无法参加iso_abbr=(即在super中调用),因为该类具有以前的列信息,不包括刚刚创建的列。

我在创建表后尝试了这段代码:

ActiveRecord::Base

因为我认为它会重新加载包含新列的列信息,但我仍然会收到错误。

如何重新加载数据,以便我可以默认Country.reset_column_information 处理该字段?

0 个答案:

没有答案