ruby-on-rails - ruby on rails activerecord data types




Gibt es eine Möglichkeit, die automatische Aktualisierung von Rails-Timestamp-Feldern zu vermeiden? (7)

Da dies ein einmaliger Import ist, könnten Sie Folgendes tun:

  1. Erstellen Sie ein Modell mit den Feldern legacy_created_at und legacy_updated_at .
  2. Alte Daten laden Ordnen Sie die gewünschten Modellfelder zu. Sie können #save und müssen sich im Allgemeinen nicht darum kümmern, update_all oder ähnliches zu verwenden, und Sie können bei Bedarf Callbacks verwenden.
  3. Erstellen Sie eine Migration, um die Spalten in created_at und updated_at .

Wenn Sie über DB-Spalten created_at und updated_at created_at updated_at Rails diese Werte beim Erstellen und Aktualisieren eines updated_at automatisch fest. Gibt es eine Möglichkeit, das Modell zu speichern, ohne diese Spalten zu berühren?

Ich bringe einige Legacy-Daten ein und möchte diese Werte aus den entsprechenden Werten in den (anders benannten) Legacy-Datenfeldern setzen. Ich finde, wenn ich sie auf das Modell setze und dann das Modell speichere, scheint Rails die eingehenden Werte zu überschreiben.

Natürlich könnte ich die Rails-Modell-Spalten einfach anders benennen, um das zu verhindern, aber nachdem die Daten importiert sind, möchte ich, dass Rails seine automatische Zeitstempel-Funktion ausführt.


Ich verwende gerne ein Mixin-Modul, um die Zeitstempelung in einem Block vorübergehend zu deaktivieren:

module WithoutTimestamps
  def without_timestamps
    old = ActiveRecord::Base.record_timestamps
    ActiveRecord::Base.record_timestamps = false
    begin
      yield
    ensure
      ActiveRecord::Base.record_timestamps = old
    end
  end
end

Dann können Sie es verwenden, wo immer Sie es brauchen

class MyModel < ActiveRecord::Base
  include WithoutTimestamps

  def save_without_timestamps
    without_timestamps do
      save!
    end
  end
end

Oder einfach nur ein Beispiel:

m = MyModel.find(1)
WithoutTimestamps.without_timestamps do
  m.save!
end


Rails 5 bietet eine bequeme Möglichkeit, einen Datensatz zu aktualisieren, ohne den Zeitstempel updated_at zu aktualisieren.

Sie müssen nur touch:false beim Aktualisieren Ihres Datensatzes.

>> user = User.first
>> user.updated_at
=> Thu, 28 Apr 2016 20:01:57 IST +05:30
>> user.name = "Jose"
>> user.save(touch: false)
=> true

>> user.updated_at
=> Thu, 28 Apr 2016 20:01:57 IST +05:30

Tun Sie dies in einer Migration oder in einer Rake-Task (oder in den neuen Datenbank-Seeds, wenn Sie auf Edge-Rails sind):

ActiveRecord::Base.record_timestamps = false
begin
  run_the_code_that_imports_the_data
ensure
  ActiveRecord::Base.record_timestamps = true  # don't forget to enable it again!
end

Sie können created_at und updated_at sicher manuell setzen, Rails wird sich nicht beschweren.

Hinweis: Dies funktioniert auch bei einzelnen Modellen, zB User.record_timestamps = false


Verwenden Sie stattdessen die update_column-Methode:

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_column

update_column(name, value)
# Updates a single attribute of an object, without calling save.

Validierung wird übersprungen.

Rückrufe werden übersprungen.

Die Spalte "updated_at / updated_on" wird nicht aktualisiert, wenn diese Spalte verfügbar ist.

Löst einen ActiveRecordError aus, wenn neue Objekte aufgerufen werden oder wenn das Attribut name als schreibgeschützt markiert ist.


record_timestamps in Rails 3+ für ein einzelnes Objekt record_timestamps für das Objekt und nicht für die Klasse fest. Dh,

>> user = User.first
>> user.updated_at
=> Tue, 12 Apr 2016 22:47:51 GMT +00:00
>> user.name = "Jose"
=> "Jose"
>> user.record_timestamps = false
>> user.save
=> true
>> user.updated_at
=> Tue, 12 Apr 2016 22:47:51 GMT +00:00
>> User.record_timestamps
=> true

Auf diese Weise berühren Sie nicht den globalen Status für das Modell, und Sie müssen nicht daran denken, die vorherige Einstellung in einem ensure wiederherzustellen.







timestamp