Ich möchte in einem bestehenden ActiveRecord-Satz das Feld created_at ändern - wie kann ich verhindern, daß ActiveRecord beim Zurückschreiben wieder den alten Wert des Feldes in die Datenbank schreibt?
mh erste spontane idee: Einfach direkt in der Datenbank ändern? Oder, Applikations abschalten und dann in der Datenbank ändern? Oder ist das keine Option? geht nicht auch einfach, record.created_at = Time.now.utc, record.save ? Das wäre logischerweise die "richtige" Lösung. Ich sehe keinen Grund warum das nicht gehen sollte, ist ja ein einfaches Attribut wie jedes andere auch. Btw. gibts einen Grund warum du nicht 3.1 verwendest? Die Asset-Pipeline ist schon eine nette Einrichtung IMO
D. I. schrieb: > geht nicht auch einfach, record.created_at = Time.now.utc, record.save ? Leider nicht - ActiveRecord übernimmt einen Wert für created_at nur, wenn der Satz neu angelegt wird. Manchmal kann man an der Intelligenz von Rails schier verzweifeln... > mh erste spontane idee: Einfach direkt in der Datenbank ändern? Eine andere Möglichkeit sehe ich im Moment auch nicht. Schön ist was anderes...
Kann ich zumindest bei Rails 3.1 nicht nachvollziehen:
1 | ruby-1.9.2-p290 :006 > item = Item.new(:tradeable => true, :useable => true) |
2 | => #<Item id: nil, tradeable: true, useable: true, created_at: nil, updated_at: nil, nr_usages: 1, depreciable: true> |
3 | ruby-1.9.2-p290 :007 > item.save |
4 | (0.2ms) SAVEPOINT active_record_1 |
5 | SQL (0.4ms) INSERT INTO `items` (`created_at`, `depreciable`, `nr_usages`, `tradeable`, `updated_at`, `useable`) VALUES ('2011-12-21 18:25:04', 1, 1, 1, '2011-12-21 18:25:04', 1) |
6 | (0.1ms) RELEASE SAVEPOINT active_record_1 |
7 | => true |
8 | ruby-1.9.2-p290 :008 > item.created_at = Time.now.utc - 1.days |
9 | => 2011-12-20 18:25:26 UTC |
10 | ruby-1.9.2-p290 :009 > item.save |
11 | (0.2ms) SAVEPOINT active_record_1 |
12 | Item::Translation Load (0.3ms) SELECT `item_translations`.* FROM `item_translations` WHERE `item_translations`.`item_id` = 515 |
13 | (0.2ms) UPDATE `items` SET `created_at` = '2011-12-20 18:25:26', `updated_at` = '2011-12-21 18:25:35' WHERE `items`.`id` = 515 |
14 | Item::Translation Load (0.3ms) SELECT `item_translations`.* FROM `item_translations` WHERE `item_translations`.`item_id` = 515 AND `item_translations`.`locale` = 'en' LIMIT 1 |
15 | Item::Translation Load (0.1ms) SELECT `item_translations`.* FROM `item_translations` WHERE `item_translations`.`item_id` = 515 AND `item_translations`.`locale` = 'en' LIMIT 1 |
16 | SQL (0.4ms) INSERT INTO `item_translations` (`created_at`, `description`, `item_id`, `locale`, `name`, `updated_at`) VALUES ('2011-12-21 18:25:35', NULL, 515, 'en', NULL, '2011-12-21 18:25:35') |
17 | (0.1ms) RELEASE SAVEPOINT active_record_1 |
18 | => true |
19 | ruby-1.9.2-p290 :010 > item.created_at |
20 | => Tue, 20 Dec 2011 18:25:26 UTC +00:00 |
21 | ruby-1.9.2-p290 :011 > |
Ja, mir scheint, da ist irgendwo ganz bös der Wurm in meinem Code drin.
Was machst du für ein Projekt mit Rails und wie/wo hostest du es?
Es ist ein kleines, nichtöffentliches Datenportal, gehostet bei Strato auf einem virtuellen Server.
Mein Problem scheint zu sein, daß ActionView created_at nicht an update im Controller zurückgibt, wenn die Funktion admin? false zurückgibt. created_at fehlt bei admin? == false in params. Kann das sein? Ich kanns selbst fast nicht glauben... Nachtrag: Es ist tatsächlich so. Ich habe meine admin? so umgebaut, daß man mit einer anderen Funktion erzwingen kann, daß sie bis auf Widerruf immer true zurückgibt. Wenn man record.attributes = params[:teilzaehlung] mit admin? == true laufen läßt, dann funktionierts... created_at scheint in params von attributes= gelöscht zu werden, wenn admin? == false ist
Das scheints doch nicht zu sein - mal gehts, mal gehts nicht...
Mh hast du da ein bisschen mehr Code? Oder zumindest Teile mit denen man das nachvollziehen kann? Hast du vielleicht irgendwo ein leeres attr_accessible im Model gesetzt und versuchst nun created_at über mass assignment zu setzen? Jedenfalls mit ein bisschen Code könnte man etwas effektiver helfen
D. I. schrieb: > Hast du vielleicht irgendwo ein leeres attr_accessible im Model gesetzt > und versuchst nun created_at über mass assignment zu setzen? Nein, da habe ich nichts selbst eingestellt. Der Wert von created_at wird immer von der DB in den html-Text transferiert und man kann die Einstellung im Browser ändern. Extrem komisch ist, daß der params-Hash mal created_at enthält und mal nicht. Mittlerweile habe ich noch eweitere Merkwürdigkeit entdeckt: Ich habe zwei Migrations gemacht:
1 | class TeilzaehlungsVon < ActiveRecord::Migration |
2 | def self.up |
3 | add_column :teilzaehlungs, :von, :datetime |
4 | end
|
5 | |
6 | def self.down |
7 | remove_column :teilzaehlungs, :von |
8 | end
|
9 | end
|
und
1 | class TeilzaehlungsVonSet < ActiveRecord::Migration |
2 | def self.up |
3 | tz = Teilzaehlung.all |
4 | ws = [] |
5 | tz.each do |b| |
6 | ws << b.id |
7 | end
|
8 | |
9 | ws.each do |b| |
10 | teilgeb = Teilzaehlung.find(b) |
11 | teilgeb.von = teilgeb.created_at |
12 | print "#{b}: #{teilgeb.created_at.to_s} #{teilgeb.von.to_s}" |
13 | teilgeb.save(false) |
14 | |
15 | t = Teilzaehlung.find(b) |
16 | print " #{t.von.to_s}\n" |
17 | end
|
18 | end
|
19 | |
20 | def self.down |
21 | end
|
22 | end
|
Die erste läuft durch und man hat hinterher die neue Spalte in der mysql-DB; alle Werte in der neuen Spalte sind erwartungsgemäß NULL. Die zweite läuft auch durch und die Printausgaben sind genau so, wie man das erwartet, nur ist hinterher in der DB die Spalte von nach wie vor überall NULL. Das riecht mir nach einer zerkloppten Rails-, oder mysql-Installation.
Uhu Uhuhu schrieb: > oder mysql-Installation Halte ich für Unwahrscheinlich... Schau dir mit dem MySQL Gui tools die Tabellendefinition an und führ' ggf. den Query mal manuell aus.
Läubi .. schrieb: > Schau dir mit dem MySQL Gui tools die Tabellendefinition an So habe ich die Information gewonnen, daß die neue Spalte konstant NULL ist. Zwischen Rails und mysql werkelt ein gem - das ist wohl dem engeren Kreis der Verdächtigen zuzurechnen.
Mach mal Rechtsklick-->Copy SQL to Clipboard (und eventuell hier posten) dann sollte man auch per Rechtsklick->Edit schauen ob es ggf. contraints auf der Spalte liegen. Wieso möchtest du überhaupt das created manipulieren?
Läubi .. schrieb: > Wieso möchtest du überhaupt das created manipulieren? Es handelt sich um Beobachtungsdatensätze, nach dem Schema Ort, Zeit, Art, Anzahl, der Zeitpunkt der Satzgenerierung ist uninteressant, weil willkürlich und dort den Beobachtungszeitpunkt einzutragen macht Sinn. Constraints sind keine auf dem Feld von.
Puh... was spricht dagegen einfach ein weiteres Feld einzufügen wenn das Created scheinbar so "tief drin im System" ist?
Das hab ich ja versucht mit den beiden Migrations, die er zwar ausgeführt hat, aber letztlich außer einer neuen, leeren Spalte nichts produziert hat, obwohl die prints erstmal darauf schließem lassen, daß alles funktioniert hat. Da ist irgenwas grundlegendes im ActiveRecord, oder im mysql-gem kaputt. Ich werde das ganze Zeug einfach nochmal neu installieren.
Uhu Uhuhu schrieb: > Ich werde das ganze Zeug einfach nochmal neu installieren. Das wird nicht helfen. Lieber auf aktuelle Version upgraden, und dann noch mal systematische Fehlersuche.
Für einen lokalen Defekt in der Entwicklungsumgebung spricht, daß es auf dem Produktionsserver ohne Mucken funktioniert.
Mittlerweile habe ich auf rails 3.1.3 aufgerüstet. Das Ergebnis ist eindeutig: das Projekt läuft jetzt überhaupt nicht mehr, weil sich mit 3.1 einfach zu viel geändert hat. Schon script/server schmiert nach ewig vielen Warnungen ab. Das Projekt wurde ursprünglich mit rails 2.3.5 begonnen und lief mit der Struktur von 2.3.5 unter 3.0.0 Gibt es irgendwo ein howto wie man ein altes Projekt auf die Struktur von 3.1 hievt?
Uhu Uhuhu schrieb: > Schon script/server schmiert nach ewig > vielen Warnungen ab. "script/server" gibt's nicht mehr, heißt jetzt "script/rails server". > Gibt es irgendwo ein howto wie man ein altes Projekt auf die Struktur > von 3.1 hievt? Sicher, Google sollte was finden. Am einfachsten: neues Projekt erstellen, deine Dateien da rein kopieren, deine Konfiguration übernehmen (nicht einfach kopieren, sondern abgleichen mit den neuen Dateien, falls sich was am Format geändert hat). Wenn du bei rails 3.0 schon deprecated-Warnungen hattest, dann kann es sein dass manche Sachen jetzt unbemerkt nicht mehr funktionieren. Gefährlichster Fallstrick: "def before_filter ..." usw. bewirkt nichts mehr, heißt jetzt "before_filter do ...".
Andreas Schwarz schrieb: > Am einfachsten: neues Projekt erstellen, deine Dateien da rein kopieren, > deine Konfiguration übernehmen Den Weg versuche ich gerade. Allerdings gibt es ein Problem, mit openssl auf Ubuntu 10.04: dort gibt es keine fertige libopenssl-ruby1.9.2 Ich werde wohl fürs erste mal mit ruby 1.8.7 weitermachen...
Ich habe RoR nicht über den Standardpaketmanager installiert sondern über rvm, so kann man bequem mehrere versionen auf der Kiste haben und einfach umschalten ohne dass sie sich beißen und alles was man braucht über gems. Evtl. gibts auch ein openssl gem? Ich weiß nicht wie groß dein Projekt schon ist, aber 3.1 bringt schon ein paar Nettigkeiten mit. Btw dein Beispiel mit den beiden Migrations hab ich mal ausprobiert, bei mir tut das ganz normal
D. I. schrieb: > Ich habe RoR nicht über den Standardpaketmanager installiert sondern > über rvm, Das hab ich jetzt auch so gemacht. > Evtl. gibts auch ein openssl gem? Sieht nicht so aus, die lib muß zur jeweils benutzten Ruby-Version passen. Die neuste auf Ubuntu 10.04 ist 1.9.1 - die RoR 3.1 nicht leiden mag...
spricht was dagegen auf ubuntu 11.10 zu gehen? Das habe ich vorkurzem auch gemacht. 10.04 LTS -> auf 11.10 allerdings über den umweg 10.10 -> 11.04 -> 11.10 von 10.10 auf 11.04 gabs bei mir nen bug, so dass die installation dann erstmal nicht mehr hochfährt, lässt sich allerdings durch GRUB neuschreiben von einer live cd beheben. Der Grund warum ich upgedated hab, war die veraltete Firefoxversion die noch nicht vernünftig mit html5 umgehen konnte. Im Zuge der Reimplementierung unseres Projekts von PHP in RoR wollten wir einfach darauf setzen. Das einzige was mich derzeit in RoR "stört" ist dass die Migrations keine datenbank foreign keys automatisch unterstützen sondern man das noch mit custom SQL machen muss, so dass es leider nicht automatisch im schema.rb landet. Es gibt zwar das Gem foreigner, aber das kann leider keine multi column foreign keys ist aber ansonsten echt klasse. Aber ok im Vergleich dazu was PHP nicht kann bin ich mit der entscheidung auf RoR umgestiegen zu sein mehr als glücklich.
D. I. schrieb: > spricht was dagegen auf ubuntu 11.10 zu gehen? Ja, auf dem Strato-VServer gibts das nicht. Mittlerweile habe ich libopenssl-ruby1.9.2 gefunden: http://www.ubuntuupdates.org/packages/show/255845 Ich werde aber doch erst mal mit 1.8.7 weiter machen, bis das Ding wieder läuft.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.