我很乐意在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
处理该字段?