Piezo Pea
Piezo Pea

Reputation: 124

Rails ActiveRecord subclass losing primary key after create

I have want to create and then update my subclass, but after creating it, it loses its primary_key, making any update impossible.

My (simplified) setup is the following:

Rails 4.2.9 ruby-2.1.10

Models:

class Contact < ActiveRecord::Base
  attr_accessible   :firstname,
                    :lastname
end

class SimpleContact < Contact
  self.primary_key  = 'id'
end

Both models sharing the contacts table (STI).

Controller:

module Public
  class FilmEntriesController < PublicController

  # ...

  def create
    logger.debug "SIM PK #{SimpleContact.primary_key}" # id

    contact = SimpleContact.create()

    logger.debug "SIM PK after create #{SimpleContact.primary_key}" # nil

    contact.update_attributes({"firstname"=>"Moe", "lastname"=>"Test"})
  end

end

The contacts table was created with this migration:

class CreateContacts < ActiveRecord::Migration
  def change
    create_table :contacts do |t|
      t.string  :firstname    # | kontakt_vorname    | varchar(64)
      t.string  :lastname     # | kontakt_nachname   | varchar(64)
      t.timestamps
    end
  end
end

The full error msg is then

ActiveRecord::StatementInvalid in Public::FilmEntriesController#create
Mysql2::Error: Unknown column 'contacts.' in 'where clause': UPDATE 
`contacts` SET `firstname` = 'Moe', `lastname` = 'Test', `updated_at` 
= '2017-09-07 11:09:39' WHERE `contacts`.`` = 21964

Thank you for any hints!

Upvotes: 1

Views: 313

Answers (2)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

To use STI you need a type column in the respective table in the database. Just add to your migration:

t.string   "type", default: "Contact", null: false

and remove

self.primary_key  = 'id'

from your model.

Upvotes: 1

Pedro Gabriel Lima
Pedro Gabriel Lima

Reputation: 1172

I guess you are having problems because you set the SimpleContact model to NOT generate a ID by itself. I'm deducting that because you are using this line of code in SimpleContact:

self.primary_key  = 'id'

and because none id is being generate.

You can check whether you set or not in you migration file for the SimpleContact table.

If that is true, one way to solve it could be use this line of code in your SimpleContact model:

before_create { self.id = generator_id() }

Where the generator_id method could be any value of id you want. That way your current code would work.

Another way to solve it would be set the SimpleContact table to generate the id by itself. You can google it to see how it is done.

Good luck!

Upvotes: 0

Related Questions