2017-09-07 1 views
1

Je veux créer puis mettre à jour ma sous-classe, mais après la création, elle perd sa clé primaire, ce qui rend toute mise à jour impossible.Rails ActiveRecord sous-classe perdre la clé primaire après créer

Ma configuration (simplifiée) est le suivant:

Rails 4.2.9 ruby-2.1.10

Modèles:

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

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

Les deux modèles partagent la table contacts (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 

Le tableau de contacts a été créé avec cette 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 

L'erreur complète msg est alors

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 

Merci pour toutes les notes!

+0

Veuillez montrer une migration de base de données pour 'contacts'. – mudasobwa

+0

Pourquoi définissez-vous 'primary_key' à' "id" '- n'est-ce pas la valeur par défaut? – Stefan

+0

@mudasobwa: j'ai ajouté la migration à la question –

Répondre

0

Je suppose que vous rencontrez des problèmes, car vous avez défini le modèle SimpleContact sur NON pour générer un ID par lui-même. Je déduisant que parce que vous utilisez cette ligne de code dans SimpleContact:

self.primary_key = 'id' 

et parce que id n'est d'être générer.

Vous pouvez vérifier si vous avez défini ou non dans votre fichier de migration pour la table SimpleContact.

Si cela est vrai, une façon de le résoudre pourrait être utiliser cette ligne de code dans votre modèle SimpleContact:

before_create { self.id = generator_id() } 

Lorsque la méthode generator_id pourrait être une valeur d'identité que vous voulez. De cette façon, votre code actuel fonctionnerait.

Une autre façon de le résoudre serait de définir la table SimpleContact pour générer l'ID par lui-même. Vous pouvez google pour voir comment c'est fait.

Bonne chance!

+0

Merci pour votre réponse! SimpleContact utilise la table 'contacts' (clarifié ma question!) Et dans la table il y a un champ' id' qui devrait être utilisé. Le problème est qu'après la création, aucun identifiant n'est défini sur l'objet créé. –

1

Pour utiliser STI, vous avez besoin d'une colonne type dans le tableau correspondant de la base de données. Il suffit d'ajouter à votre migration:

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

et enlever

self.primary_key = 'id' 

de votre modèle.

+0

Merci pour votre réponse, peut-être que j'ai tort, mais je n'ai pas besoin de spécification de type. C'est suffisant si SimpleContact écrit dans Contact. Pensez-vous que cela pourrait être un problème pour Rails/AR? –

+2

"Je n'ai pas besoin de la spécification de type" - vous ne le faites pas, mais Rails ** do **, ils doivent savoir quelle classe instancier. – mudasobwa

+0

"vous n'avez pas, mais Rails faire" - <3 –