Juke Seroon Juke Seroon - 1 year ago 99
MySQL Question

Rails has_many/belongs_to on custom database ActiveRecord::AssociationTypeMismatch got Fixnum

I have the database from another non-rails project so I have to deal with unordinary column names. I have the model Category:

self.primary_key = "categoryID"
has_many :products, foreign_key: "category", primary_key: "categoryID"

And the model Product:

self.primary_key = "productID"
belongs_to :category, foreign_key: "category", primary_key: "categoryID"

In the Product's table there's a foreign key "category" which stores a primary key of Category's table, which is "categoryID". I'm trying to create a product in a console like that:

c = Category.last
p = c.products.create

And I get an error:

ActiveRecord::AssociationTypeMismatch: Category(#29703600) expected, got Fixnum(#17843240)

I tried some other ways to create a product where I could pass the Category instance there but it leads to other weird errors. So now I just want this way to work.
Where is a problem?

Answer Source

I think the problem is that you have category column (so Rails creates category method for it) and category association with the same name.
You can give some another name to association

I created test app

class CreateProducts < ActiveRecord::Migration
  def change
    create_table :products, id: false do |t|
      t.integer :productID
      t.integer :category
      t.string  :title

class CreateCategories < ActiveRecord::Migration
  def change
    create_table :categories, id: false do |t|
      t.integer :categoryID
      t.string  :title

class Product < ActiveRecord::Base
  self.primary_key = :productID

  belongs_to :my_category, class_name: 'Category', foreign_key: :category

class Category < ActiveRecord::Base
  self.primary_key = :categoryID

  has_many :products, foreign_key: :category

This way the following code seems to work fine

c = Category.create categoryID: 1, title: 'First category'
c.products # => []
c.products.create productID: 1, title: 'First product' 
c.products.create productID: 2, title: 'Second product'
c.products # => #<ActiveRecord::Associations::CollectionProxy [#<Product productID: 1, category: 1, title: "First product">, #<Product productID: 2, category: 1, title: "Second product">]>

p = Product.first
p.category # => 1
p.my_category # => #<Category categoryID: 1, title: "First category">
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download