I have the following code in my Rails 'seeds.rb' file:
acondigitaladdresslineone = Addressline.create!(address_id: acondigitaladdress.id, address: "Sørkedalsveien 273", address_line_position: 0)
The 'Address' model has a one-to-many relation with the 'Addressline' model, and the respective 'belongs_to' and 'has_many' declarations are properly in place. Here is the content of the migration files:
class CreateAddresses < ActiveRecord::Migration[5.0]
def change
create_table :addresses do |t|
t.references :towncity, foreign_key: true
t.references :stateregion, foreign_key: true, null: true
t.references :postalcode, foreign_key: true
t.timestamps
end
end
end
class CreateAddresslines < ActiveRecord::Migration[5.0]
def change
create_table :addresslines do |t|
t.references :address, foreign_key: true
t.string :address
t.integer :address_line_position
t.timestamps
end
end
end
When I run the Rails Console, I receive the following error, which refers to the "acondigitaladdresslineone = ..." line of code:
ActiveRecord::AssociationTypeMismatch: Address(#8269560) expected, got String(#6922340)
I corrected the error by making the following changes:
# From the 'CreateAddresslines' migration file
# Original code
t.string :address
# Revised code
t.string :address_name
# From the 'acondigitaladdresslineone' variable declaration line
# Original code
address: "Sørkedalsveien 273"
# Revised code
address_name: "Sørkedalsveien 273"
I suspect the cause of the error possibly is due the underlying database's (in this case SQLite) inability to disambiguate the same field name based upon datatype. For example, in the original version of the 'CreateAddresslines' migration file, SQLlite raises an error as a result of these two declarations:
t.references :address, foreign_key: true
t.string :address
It is easy to overlook the obvious when entangled in coding. Clearly, a relational database table cannot have two or more columns with the same name. I am unaware of any relational database management system having a capability to disambiguate same-named table columns based upon differences in their datatypes.
I need a sanity check. Is this a reasonable assumption why the 'AssociationTypeMismatch' error was raised?
Thank you.
t.references :address
will create the column address_id
so there should be no conflict with t.string :address
on the DB level.
The problem occurs in ActiveRecord when accessors and associations are declared.
ActiveRecord reads the schema from the database and uses it to create attributes and accessor methods in your models for each column. This happens before any of the code in the class declaration block is evaluated.
When you then create an association you are overwriting the #address
and #address=
methods created for the string attribute.
class Addressline
belongs_to :address
end
Which is why when you do:
Addressline.new(address: 'Foo')
You get a type error since the #address=
setter method is setting address_id
and expects an Address instance.
The solution is as you might have surmised is to not name other columns the same thing as your associations. Just rename the column:
class FixColumnName < ActiveRecord::Migration
def self.change
# call it whatever you want, but not address!
rename_column :addresslines, :address, :value
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.