88 Stimmen

Wie kann ich mit Rails meinen Primärschlüssel so einstellen, dass es sich nicht um eine Spalte mit dem Typ Integer handelt?

Ich verwende Rails-Migrationen, um ein Datenbankschema zu verwalten, und ich erstelle eine einfache Tabelle, in der ich einen nicht-ganzzahligen Wert als Primärschlüssel verwenden möchte (insbesondere eine Zeichenfolge). Um von meinem Problem zu abstrahieren, nehmen wir an, es gibt eine Tabelle employees wobei die Mitarbeiter durch eine alphanumerische Zeichenfolge identifiziert werden, z. B. "134SNW" .

Ich habe versucht, die Tabelle in einer Migration wie dieser zu erstellen:

create_table :employees, {:primary_key => :emp_id} do |t|
    t.string :emp_id
    t.string :first_name
    t.string :last_name
end

Das Ergebnis ist, dass die folgende Zeile anscheinend völlig ignoriert wurde t.string :emp_id und machte daraus eine Integer-Spalte. Gibt es eine andere Möglichkeit, wie Rails die PRIMARY_KEY-Beschränkung (ich verwende PostgreSQL) für mich generieren kann, ohne dass ich die SQL in einer execute anrufen?

ANMERKUNG : Ich weiß, dass es nicht am besten ist, String-Spalten als Primärschlüssel zu verwenden, also bitte keine Antworten, die nur sagen, dass man einen Integer-Primärschlüssel hinzufügen soll. Ich werde vielleicht trotzdem einen hinzufügen, aber die Frage ist immer noch gültig.

2voto

BvuRVKyUVlViVIc7 Punkte 11466

Sie müssen die Option :id => false verwenden

create_table :employees, :id => false, :primary_key => :emp_id do |t|
    t.string :emp_id
    t.string :first_name
    t.string :last_name
end

1voto

Vijay Sali Punkte 1013

Wie wäre es mit dieser Lösung?

Innerhalb des Mitarbeitermodells, warum können wir nicht Code hinzufügen, der auf Einzigartigkeit in der Spalte prüft, z. B.: Nehmen Sie an, dass Mitarbeiter ein Modell ist, in dem Sie EmpId haben, das eine Zeichenfolge ist, für die wir hinzufügen können ":Einzigartigkeit => wahr" zu EmpId

    class Employee < ActiveRecord::Base
      validates :EmpId , :uniqueness => true
    end

Ich bin mir nicht sicher, ob das die Lösung ist, aber bei mir hat es funktioniert.

1voto

engineerDave Punkte 3841

Ich weiß, dies ist ein alter Thread, über den ich gestolpert bin... aber ich bin irgendwie schockiert, dass niemand DataMapper erwähnt hat.

Ich finde, wenn Sie aus der ActiveRecord-Konvention abweichen müssen, ist dies eine gute Alternative. Auch seine einen besseren Ansatz für Legacy und Sie können die Datenbank "as-is" unterstützen.

Ruby Object Mapper (DataMapper 2) ist vielversprechend und baut ebenfalls auf AREL-Prinzipien auf!

1voto

Guster Punkte 1364

Hinzufügen Index funktioniert für mich, ich bin mit MySql btw.

create_table :cards, {:id => false} do |t|
    t.string :id, :limit => 36
    t.string :name
    t.string :details
    t.datetime :created_date
    t.datetime :modified_date
end
add_index :cards, :id, :unique => true

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X