Gibt es eine Möglichkeit, den ID-Wert eines Modells beim Erstellen zu überschreiben? Etwas wie:
Post.create(:id => 10, :title => 'Test')
wäre ideal, wird aber offensichtlich nicht funktionieren.
ruby-on-rails
activerecord
Codebeef
quelle
quelle
Antworten:
id ist nur attr_protected, weshalb Sie die Massenzuweisung nicht verwenden können, um sie festzulegen. Wenn Sie es jedoch manuell einstellen, funktioniert es einfach:
Ich bin mir nicht sicher, was die ursprüngliche Motivation war, aber ich mache das, wenn ich ActiveHash-Modelle in ActiveRecord konvertiere. Mit ActiveHash können Sie in ActiveRecord dieselbe Semantik zur Zugehörigkeit verwenden. Anstatt jedoch eine Migration durchzuführen und eine Tabelle zu erstellen und bei jedem Aufruf den Overhead der Datenbank zu verursachen, speichern Sie Ihre Daten einfach in yml-Dateien. Die Fremdschlüssel in der Datenbank verweisen auf die speicherinternen IDs in der yml.
ActiveHash eignet sich hervorragend für Auswahllisten und kleine Tabellen, die sich nur selten und nur von Entwicklern ändern. Wenn Sie also von ActiveHash zu ActiveRecord wechseln, ist es am einfachsten, alle Fremdschlüsselreferenzen gleich zu halten.
quelle
ActiveRecord::VERSION::STRING == "3.2.11"
hier (mit dem sqlite3-Adapter) und das oben genannte funktioniert für mich.Versuchen
das sollte dir geben, wonach du suchst.
quelle
Sie könnten auch so etwas verwenden:
Obwohl dies in den Dokumenten angegeben ist , wird dadurch die Sicherheit der Massenzuweisung umgangen.
quelle
Für Schienen 4:
Andere Rails 4-Antworten haben bei mir nicht funktioniert. Viele von ihnen schienen sich bei der Überprüfung mit der Rails-Konsole zu ändern, aber als ich die Werte in der MySQL-Datenbank überprüfte, blieben sie unverändert. Andere Antworten funktionierten nur manchmal.
Zumindest für MySQL
id
funktioniert das Zuweisen einer ID-Nummer unter der automatischen Inkrementierung nur , wenn Sie sie verwendenupdate_column
. Beispielsweise,Wenn Sie
create
zunew
+ wechseln , trittsave
dieses Problem weiterhin auf. Manuelles Ändern derid
Artp.id = 10
erzeugt ebenfalls dieses Problem.Im Allgemeinen würde ich das
update_column
ändernid
, obwohl es eine zusätzliche Datenbankabfrage kostet, da es die ganze Zeit funktioniert. Dies ist ein Fehler, der möglicherweise nicht in Ihrer Entwicklungsumgebung angezeigt wird, aber Ihre Produktionsdatenbank stillschweigend beschädigen kann, während Sie sagen, dass sie funktioniert.quelle
Post.new.update(id: 10, title: 'Test')
Tatsächlich stellt sich heraus, dass Folgendes funktioniert:
quelle
validate: false
, anstatt einfachfalse
. Sie stoßen jedoch immer noch auf das Problem mit geschützten Attributen - es gibt einen separaten Weg, um das zu umgehen, was ich in meiner Antwort beschrieben habe.Wie Jeff betont, verhält sich id so, als wäre es attr_protected. Um dies zu verhindern, müssen Sie die Liste der standardmäßig geschützten Attribute überschreiben. Seien Sie überall dort vorsichtig, wo Attributinformationen von außen kommen können. Das ID-Feld ist aus einem bestimmten Grund standardmäßig geschützt.
(Getestet mit ActiveRecord 2.3.5)
quelle
Wir können Attribute_protected_by_default überschreiben
quelle
Dies scheint mir nicht das zu sein, was Sie normalerweise tun möchten, aber es funktioniert ganz gut, wenn Sie eine Tabelle mit einem festen Satz von IDs füllen müssen (z. B. wenn Sie Standardeinstellungen mit einer Rechenaufgabe erstellen) und Sie Sie möchten die automatische Inkrementierung überschreiben (damit die Tabelle jedes Mal, wenn Sie die Aufgabe ausführen, mit denselben IDs gefüllt wird):
quelle
Fügen Sie diese Funktion create_with_id oben in Ihre seeds.rb ein und verwenden Sie sie dann, um Ihre Objekterstellung durchzuführen, wenn explizite IDs gewünscht werden.
und benutze es so
anstatt zu verwenden
Foo.create({id:1,name:"My Foo",prop:"My other property"})
quelle
Dieser Fall ist ein ähnliches Problem, das erforderlich war, um das
id
mit einer Art benutzerdefiniertem Datum zu überschreiben :Und dann :
Rückrufe funktionieren gut.
Viel Glück!.
quelle
id
auf Unix basierenden Zeitstempel erstellen . Ich habe das drinnen gemachtbefore_create
. Funktioniert gut.Für Rails 3 ist der einfachste Weg, dies zu tun, die Verwendung
new
mit derwithout_protection
Verfeinerung und dannsave
:Für Seed-Daten kann es sinnvoll sein, die Validierung zu umgehen, was Sie folgendermaßen tun können:
Wir haben ActiveRecord :: Base tatsächlich eine Hilfsmethode hinzugefügt, die unmittelbar vor der Ausführung von Seed-Dateien deklariert wird:
Und nun:
Für Rails 4 sollten Sie StrongParams anstelle von geschützten Attributen verwenden. In diesem Fall können Sie einfach zuweisen und speichern, ohne Flags an
new
folgende Adresse zu übergeben :quelle
{}
wie Samuels Antwort oben (Rails3) einzugeben.id
ist noch 10.id
wurde als 10 übergeben - genau das sollte es also sein. Wenn Sie das nicht erwartet haben, können Sie dies anhand eines Beispiels klären?Funktioniert in Rails 4.2.1 mit Postgresql 9.5.3,
Post.create(:id => 10, :title => 'Test')
solange noch keine Zeile mit id = 10 vorhanden ist.quelle
Sie können die ID per SQL einfügen:
quelle