Zmiana nazwy utworzonych w, zaktualizowanych w kolumnach ActiveRecord/Rails
Chcę zmienić nazwę kolumn timestamp zdefiniowanych w timestamp.rb . Czy metody znacznika czasu.RB być nadpisane? I co należy zrobić w aplikacji, aby moduł z nadpisanymi metodami został użyty.
9 answers
Nie ma na to prostego sposobu. Możesz to osiągnąć poprzez nadpisanie modułu ActiveRecord:: Timestamp lub napisanie własnego, aby zrobić za Ciebie magię.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-09 10:33:01
Można to zrobić poprzez napisanie metody modułu ActiveRecord:: Timestamp. Nie nadpisuje całego modułu. Muszę osiągnąć ten sam cel, ponieważ pracuję ze starszą bazą danych. Jestem na rails 3 i zacząłem podążać za metodologią jak zrobić łatkę mojego kodu z nadpisywaniem funkcjonalności rails.
Najpierw tworzę projekt bazowy, z którym pracuję i tworzę plik o tej nazwie w inicjalizatorach. W tym przypadku stworzyłem active_record.rb. A w pliku umieściłem kod, aby zastąpić dwie metody, które kontrolowały znacznik czasu. Poniżej znajduje się próbka mojego kodu:
module ActiveRecord
module Timestamp
private
def timestamp_attributes_for_update #:nodoc:
["updated_at", "updated_on", "modified_at"]
end
def timestamp_attributes_for_create #:nodoc:
["created_at", "created_on"]
end
end
end
Uwaga: chciałbym również wspomnieć, że tego rodzaju łatanie małp, aby wszystko działało, jest źle widziane i może pękać na aktualizacjach, więc bądźcie ostrożni i bądźcie w pełni świadomi tego, co chcecie robić.
Aktualizacje:
- zmiana nazw kolumn znacznika czasu z symbolu na ciąg znaków dla zmiana api. Dzięki. Techbrunch za zwrócenie mojej uwagi na tę zmianę API.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-13 01:27:14
Myślę, że metoda Npatela jest właściwym podejściem, ale robi zbyt wiele, jeśli trzeba tylko zmienić #created_at na jednym modelu. Ponieważ moduł znacznika czasu jest zawarty w każdym obiekcie AR, można go zastąpić dla każdego modelu, a nie globalnie.
class User < ActiveRecord::Base
...
private
def timestamp_attributes_for_create
super << :registered_at
end
end
Rails ~> 5.1
private_class_method
def self.timestamp_attributes_for_create
super << :registered_at
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-13 12:45:39
Możesz użyć metod beforesave i beforecreate, aby opublikować DateTime.teraz do określonych kolumn.
class Sample < ActiveRecord::Base
before_create :set_time_stamps
before_save :set_time_stamps
private
def set_time_stamps
self.created_column = DateTime.now if self.new_record?
self.updated_column = DateTime.now
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-20 16:04:04
Quick ugly hack, opracowany z odpowiedzi Milana Novoty: Dołącz następujące do środowiska.rb, zastępując wartości stałych CREATED_COL i UPDATED_COL żądanymi nazwami kolumn:
module ActiveRecord
module Timestamp
CREATED_COL = 'created_at'
UPDATED_COL = 'updated_at'
private
def create_with_timestamps #:nodoc:
if record_timestamps
t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
write_attribute(CREATED_COL, t) if respond_to?(CREATED_COL) && send(CREATED_COL).nil?
write_attribute(UPDATED_COL, t) if respond_to?(UPDATED_COL) && send(UPDATED_COL).nil?
end
create_without_timestamps
end
def update_with_timestamps(*args) #:nodoc:
if record_timestamps && (!partial_updates? || changed?)
t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
write_attribute(UPDATED_COL, t) if respond_to?(UPDATED_COL)
end
update_without_timestamps(*args)
end
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-09 16:22:13
Poprawna składnia do robienia tego w rails 4.2
class User < ActiveRecord::Base
...
private
def timestamp_attributes_for_create
super << 'date_add'
end
def timestamp_attributes_for_update
super << 'date_update'
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-13 09:38:43
LUB możesz po prostu utworzyć własne kolumny (DateTime) i ręcznie ustawić kolumnę created_at podczas tworzenia i ustawić kolumnę updated_at podczas aktualizacji. To może być łatwiejsze niż hack powyżej. To właśnie zrobię. Jeszcze lepiej, zaktualizuj rails, aby umożliwić nam zmianę tych nazw.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-09 19:37:55
Sol ' n, który nie używa plastra małpy; użyj reversible
blokowanie podczas migracji:
class CreateTest < ActiveRecord::Migration
def change
create_table :test do |t|
end
# set the timestamp columns default to now()
reversible do |dir|
dir.up do
tables = [
:test
]
tables.each do |t|
execute <<-SQL
ALTER TABLE #{t.to_s}
add column created timestamp without time zone default now();
SQL
execute <<-SQL
ALTER TABLE #{t.to_s}
add column updated timestamp without time zone default now();
SQL
end
end
dir.down do
# no need to do anything, the rollback will drop the tables
end
end
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-02 21:53:15
An zaktualizowano anwser dla Rails >= 5.1 . Sugerowałbym użycie ApplicationRecord
, który jest domyślnie dostępny w Twojej aplikacji i zdefiniowanie:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
class << self
private
def timestamp_attributes_for_create
super << 'my_created_at_column'
end
def timestamp_attributes_for_update
super << 'my_updated_at_column'
end
end
end
Zauważ, że możesz również użyć tego bloku dla określonego modelu, jeśli nie chcesz go skonfigurować dla wszystkich modeli.
Zauważ również, że powinieneś używać łańcuchów, a nie symboli.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-11 13:17:35