Rails: jak ustawić domyślne wartości w ActiveRecord?
Jak ustawić wartość domyślną w ActiveRecord?
Widzę post od Pratika, który opisuje brzydki, skomplikowany fragment kodu: http://m.onkey.org/2007/7/24/how-to-set-default-values-in-your-model
class Item < ActiveRecord::Base
def initialize_with_defaults(attrs = nil, &block)
initialize_without_defaults(attrs) do
setter = lambda { |key, value| self.send("#{key.to_s}=", value) unless
!attrs.nil? && attrs.keys.map(&:to_s).include?(key.to_s) }
setter.call('scheduler_type', 'hotseat')
yield self if block_given?
end
end
alias_method_chain :initialize, :defaults
end
Widziałem następujące przykłady googlowania:
def initialize
super
self.status = ACTIVE unless self.status
end
I
def after_initialize
return unless new_record?
self.status = ACTIVE
end
Widziałem też, jak ludzie umieszczają go w swojej migracji, ale wolałbym, aby został zdefiniowany w kodzie modelu.
Czy istnieje kanoniczny sposób ustawienia domyślnej wartość dla pól w modelu ActiveRecord?
28 answers
Istnieje kilka problemów z każdą z dostępnych metod, ale uważam, że zdefiniowanie wywołania zwrotnego after_initialize
jest sposobem na przejście z następujących powodów:
-
default_scope
zainicjalizuje wartości dla nowych modeli, ale wtedy będzie to Zakres, na którym znajduje się model. Jeśli po prostu chcesz zainicjalizować niektóre liczby na 0, to jest to , a nie to, czego chcesz. - Definiowanie domyślnych wartości w migracji również działa przez pewien czas... Jak już wspomniano to czy Nie będzie działać, gdy tylko wywołasz Model.nowy.
- nadpisywanie
initialize
może działać, ale nie zapomnij zadzwonićsuper
! - używanie wtyczki takiej jak phusion ' s staje się nieco śmieszne. To jest ruby, czy naprawdę potrzebujemy wtyczki, aby zainicjować niektóre wartości domyślne?
- Overriding
after_initialize
jest przestarzałe od Rails 3. Kiedy nadpisujęafter_initialize
w rails 3.0.3 otrzymuję następujące ostrzeżenie w konsoli:
OSTRZEŻENIE O DEPRECJACJI: Base # after_initialize został wycofany, Proszę użyć Base.zamiast tego metoda after_initialize:. (wywołane z /Users / me / myapp / app / models / my_model:15)
Dlatego powiedziałbym napisać wywołanie zwrotne after_initialize
, które pozwala na domyślne atrybuty oprócz pozwalając ustawić domyślne skojarzenia w taki sposób:
class Person < ActiveRecord::Base
has_one :address
after_initialize :init
def init
self.number ||= 0.0 #will set the default value only if it's nil
self.address ||= build_address #let's you set a default association
end
end
Teraz masz tylko jedno miejsce , aby szukać inicjalizacji swoich Modeli. Używam tej metody, dopóki ktoś nie wymyśli lepszego jeden.
Zastrzeżenia:
-
Dla pól logicznych do:
self.bool_field = true if self.bool_field.nil?
Zobacz komentarz Paula Russella do tej odpowiedzi po więcej szczegółów
-
Jeśli wybierasz tylko podzbiór kolumn dla modelu (tj. używając
select
w zapytaniu takim jakPerson.select(:firstname, :lastname).all
), otrzymaszMissingAttributeError
, jeśli twoja metodainit
uzyska dostęp do kolumny, która nie została uwzględniona w klauzuliselect
. Można się przed tym uchronić w ten sposób:self.number ||= 0.0 if self.has_attribute? :number
I dla boolean kolumna...
self.bool_field = true if (self.has_attribute? :bool_value) && self.bool_field.nil?
Zauważ również, że składnia jest inna przed Rails 3.2 (zobacz komentarz Cliffa Darlinga poniżej)
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
2017-07-11 02:14:21
Rails 5+
Możesz użyć metodyatrybutu w swoich modelach, np.:
class Account < ApplicationRecord
attribute :locale, :string, default: 'en'
end
Można również przekazać lambda do parametru default
. Przykład:
attribute :uuid, :string, default: -> { SecureRandom.uuid }
Drugim argumentem jest type i może to być również niestandardowa instancja klasy type, na przykład:
attribute :uuid, UuidType.new, default: -> { SecureRandom.uuid }
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
2020-07-06 06:35:00
Wprowadzamy wartości domyślne do bazy danych poprzez migracje (poprzez podanie opcji :default
w definicji każdej kolumny) i pozwalamy Active Record używać tych wartości do ustawiania wartości domyślnych dla każdego atrybutu.
IMHO, to podejście jest zgodne z zasadami AR: convention over configuration, DRY, definicja tabeli napędza model, a nie na odwrót.
Zauważ, że domyślne wartości są nadal w kodzie aplikacji (Ruby), choć nie w modelu, ale w migracja (s).
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
2008-11-30 13:45:52
Niektóre proste przypadki mogą być obsługiwane przez zdefiniowanie domyślnej wartości w schemacie bazy danych, ale to nie obsługuje wielu trudniejszych przypadków, w tym obliczonych wartości i kluczy innych modeli. W takich przypadkach robię to:
after_initialize :defaults
def defaults
unless persisted?
self.extras||={}
self.other_stuff||="This stuff"
self.assoc = [OtherModel.find_by_name('special')]
end
end
Zdecydowałem się użyć after_initialize, ale nie chcę, aby było stosowane do obiektów, które znajdują się tylko te nowe lub utworzone. Myślę, że to prawie szokujące, że wywołanie zwrotne after_new nie jest przewidziane dla tego oczywistego przypadku użycia, ale zrobiłem to, potwierdzając czy obiekt jest już utrzymany, wskazując, że nie jest nowy.
Po obejrzeniu odpowiedzi Brada Murraya jest to jeszcze czystsze, jeśli warunek zostanie przeniesiony na żądanie wywołania zwrotnego:
after_initialize :defaults, unless: :persisted?
# ":if => :new_record?" is equivalent in this context
def defaults
self.extras||={}
self.other_stuff||="This stuff"
self.assoc = [OtherModel.find_by_name('special')]
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-05-28 15:05:36
Wzorzec wywołania zwrotnego after_initialize można poprawić, wykonując następujące czynności
after_initialize :some_method_goes_here, :if => :new_record?
Ma to niebanalną korzyść, jeśli twój kod init musi radzić sobie z asocjacjami, ponieważ poniższy kod wyzwala subtelne n+1, jeśli przeczytasz początkowy rekord bez włączania skojarzonego.
class Account
has_one :config
after_initialize :init_config
def init_config
self.config ||= build_config
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
2012-09-14 05:37:50
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
2008-11-30 09:42:56
Jeszcze lepszym / czystszym potencjalnym sposobem niż proponowane odpowiedzi jest nadpisanie accesora, jak to:
def status
self['status'] || ACTIVE
end
Zobacz "nadpisywanie domyślnych accesorów" w dokumentacji ActiveRecord::Basei Więcej informacji ze StackOverflow na temat używania self.
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
2017-05-23 12:26:37
Używam attribute-defaults
gem
Z dokumentacji:
uruchom sudo gem install attribute-defaults
i dodaj require 'attribute_defaults'
do swojej aplikacji.
class Foo < ActiveRecord::Base
attr_default :age, 18
attr_default :last_seen do
Time.now
end
end
Foo.new() # => age: 18, last_seen => "2014-10-17 09:44:27"
Foo.new(:age => 25) # => age: 25, last_seen => "2014-10-17 09:44:28"
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
2014-10-16 22:46:39
Podobne pytania, ale wszystkie mają nieco inny kontekst: - Jak utworzyć domyślną wartość atrybutów w modelu Rails activerecord?
Najlepsza odpowiedź: zależy, czego chcesz!
jeśli chcesz, aby każdy obiekt zacznij od wartości: użyj after_initialize :init
Chcesz, aby Formularz new.html
miał domyślną wartość po otwarciu strony? use https://stackoverflow.com/a/5127684/1536309
class Person < ActiveRecord::Base
has_one :address
after_initialize :init
def init
self.number ||= 0.0 #will set the default value only if it's nil
self.address ||= build_address #let's you set a default association
end
...
end
jeśli chcesz każdy obiekt do mieć wartość obliczoną na podstawie danych wejściowych użytkownika: use before_save :default_values
Chcesz, aby użytkownik wprowadził X
, a następnie Y = X+'foo'
? użycie:
class Task < ActiveRecord::Base
before_save :default_values
def default_values
self.status ||= 'P'
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
2017-05-23 12:10:47
Widziałem też, jak ludzie umieszczają to w swoich migracjach, ale wolałbym to zobaczyć zdefiniowany w kodzie modelu.
Czy istnieje kanoniczny sposób ustawiania wartości domyślnej dla pól w Model ActiveRecord?
Sposobem kanonicznym Rails, przed Rails 5, było ustawienie go w migracji i po prostu zajrzyj do db/schema.rb
, Gdy chcesz zobaczyć, jakie domyślne wartości są ustawiane przez DB dla dowolnego modelu.
Wbrew temu, co stwierdza odpowiedź @Jeff Perrin (co jest nieco stare), podejście migracyjne zastosuje nawet domyślne przy użyciu Model.new
, ze względu na magię Rails. Sprawdzona praca w Rails 4.1.16.
Najprostsza rzecz jest często najlepsza. Mniej wiedzy i potencjalnych punktów zamieszania w kodzie. I to "po prostu działa".
class AddStatusToItem < ActiveRecord::Migration
def change
add_column :items, :scheduler_type, :string, { null: false, default: "hotseat" }
end
end
Lub, aby zmienić kolumnę bez tworzenia nowej, wykonaj albo:
class AddStatusToItem < ActiveRecord::Migration
def change
change_column_default :items, :scheduler_type, "hotseat"
end
end
A może nawet lepiej:
class AddStatusToItem < ActiveRecord::Migration
def change
change_column :items, :scheduler_type, :string, default: "hotseat"
end
end
Sprawdź oficjalny przewodnik RoR dla opcji zmiany kolumny metody.
null: false
wyłącza wartości NULL w DB i, jako dodatkową korzyść, aktualizuje również tak, że wszystkie wcześniej istniejące rekordy DB, które były wcześniej null, są ustawiane z wartością domyślną dla tego pola. Możesz wykluczyć ten parametr w migracji, jeśli chcesz, ale uważam, że jest bardzo przydatny!
class Item < ActiveRecord::Base
attribute :scheduler_type, :string, default: 'hotseat'
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
2020-05-11 08:48:48
po to są konstruktorzy! Nadpisuje metodę initialize
modelu.
Użyj metody after_initialize
.
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-11-13 09:56:19
Sup chłopaki, skończyłem robiąc co następuje:
def after_initialize
self.extras||={}
self.other_stuff||="This stuff"
end
Działa jak czar!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-27 06:36:21
Odpowiedź jest od dawna, ale często potrzebuję wartości domyślnych i wolę nie umieszczać ich w bazie danych. Tworzę DefaultValues
:
module DefaultValues
extend ActiveSupport::Concern
class_methods do
def defaults(attr, to: nil, on: :initialize)
method_name = "set_default_#{attr}"
send "after_#{on}", method_name.to_sym
define_method(method_name) do
if send(attr)
send(attr)
else
value = to.is_a?(Proc) ? to.call : to
send("#{attr}=", value)
end
end
private method_name
end
end
end
A potem używaj go w moich modelach w ten sposób:
class Widget < ApplicationRecord
include DefaultValues
defaults :category, to: 'uncategorized'
defaults :token, to: -> { SecureRandom.uuid }
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-02-14 21:35:41
Napotkałem problemy z after_initialize
podawaniem błędów ActiveModel::MissingAttributeError
przy wykonywaniu skomplikowanych znalezisk:
Eg:
@bottles = Bottle.includes(:supplier, :substance).where(search).order("suppliers.name ASC").paginate(:page => page_no)
"szukaj" w .where
to hash warunków
Więc skończyło się na tym, że zrobiłem to przez nadpisanie initialize w ten sposób:
def initialize
super
default_values
end
private
def default_values
self.date_received ||= Date.current
end
Wywołanie super
jest konieczne, aby upewnić się, że obiekt inicjalizuje się poprawnie z ActiveRecord::Base
przed wykonaniem mojego niestandardowego kodu, czyli: default_values
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
2012-11-30 03:24:52
Problem z rozwiązaniami after_initialize polega na tym, że musisz dodać after_initialize do każdego obiektu, który wyszukujesz poza DB, niezależnie od tego, czy masz dostęp do tego atrybutu, czy nie. Proponuję leniwe podejście.
Metody atrybutów (gettery) są oczywiście same w sobie, więc można je nadpisać i podać domyślne. Coś w stylu:
Class Foo < ActiveRecord::Base
# has a DB column/field atttribute called 'status'
def status
(val = read_attribute(:status)).nil? ? 'ACTIVE' : val
end
end
Chyba, że, jak ktoś wskazał, musisz zrobić Foo.find_by_status ('aktywny'). W takim razie myślę, że naprawdę musisz ustawić domyślne ograniczenia w swojej bazie danych, jeśli DB obsługuje to.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
2012-09-08 00:43:17
class Item < ActiveRecord::Base
def status
self[:status] or ACTIVE
end
before_save{ self.status ||= ACTIVE }
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
2013-07-15 07:59:14
Chociaż robienie tego przy ustawianiu wartości domyślnych jest w większości przypadków mylące i niewygodne, możesz również użyć :default_scope
. Zobacz komentarz squila tutaj .
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-21 12:57:32
Metoda After_initialize jest przestarzała, zamiast tego użyj funkcji zwrotnej.
after_initialize :defaults
def defaults
self.extras||={}
self.other_stuff||="This stuff"
end
Jednak użycie : default w Twoich migracjach jest nadal najczystszym sposobem.
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-10-17 01:59:13
Odkryłem, że użycie metody walidacji zapewnia dużą kontrolę nad ustawieniami domyślnymi. Możesz nawet ustawić domyślne wartości (lub nieudaną walidację) dla aktualizacji. Możesz nawet ustawić inną wartość domyślną dla wstawek i aktualizacji, jeśli naprawdę chcesz. Zauważ, że wartość domyślna nie będzie ustawiona do #valid? nazywa się.
class MyModel
validate :init_defaults
private
def init_defaults
if new_record?
self.some_int ||= 1
elsif some_int.nil?
errors.add(:some_int, "can't be blank on update")
end
end
end
Jeśli chodzi o definiowanie metody after_initialize, mogą wystąpić problemy z wydajnością, ponieważ after_initialize jest również wywoływany przez każdy obiekt zwracany przez: find : http://guides.rubyonrails.org/active_record_validations_callbacks.html#after_initialize-and-after_find
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
2011-03-30 21:24:23
Jeśli kolumna stanie się kolumną typu "status", a twój model nadaje się do użycia maszyn stanowych, rozważ użycie AASM gem , po czym możesz po prostu zrobić
aasm column: "status" do
state :available, initial: true
state :used
# transitions
end
Nadal nie inicjalizuje wartości dla niezapisanych rekordów, ale jest nieco czystsza niż nagrywanie własnych z init
czy cokolwiek innego, a Ty czerpiesz inne korzyści z aasm, takie jak zakresy dla wszystkich swoich statusów.
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
2013-11-11 22:30:44
Https://github.com/keithrowell/rails_default_value
class Task < ActiveRecord::Base
default :status => 'active'
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-03-24 12:39:31
Zdecydowanie sugeruję użycie klejnotu "default_value_for": https://github.com/FooBarWidget/default_value_for
Istnieje kilka trudnych scenariuszy, które wymagają nadpisania metody initialize, co robi ten gem.
Przykłady:
Domyślną wartością db jest NULL, domyślną wartością zdefiniowaną przez model/ruby jest "jakiś łańcuch", ale w rzeczywistości chcesz ustawić wartość na nil z dowolnego powodu: MyModel.new(my_attr: nil)
Większość rozwiązań tutaj nie ustawia wartości na nil, a zamiast tego ustawi ją na domyślną.
Ok, więc zamiast podejść ||=
, przełącz się na my_attr_changed?
...
Ale wyobraź sobie, że domyślną wartością db jest "some string", domyślną wartością zdefiniowaną przez model/ruby jest "some other string", ale w określonym scenariuszu, chcesz ustawić wartość na" some string " (domyślna wartość db): MyModel.new(my_attr: 'some_string')
Spowoduje to, że my_attr_changed?
będzie false , ponieważ wartość odpowiada wartości domyślnej db, która z kolei odpali Twoje domyślny kod zdefiniowany przez ruby i ustaw wartość na "jakiś inny ciąg" -- ponownie, nie to, co chciałeś.
Z tych powodów nie wydaje mi się, aby można było to osiągnąć za pomocą haka after_initialize.
Ponownie myślę, że klejnot "default_value_for" przyjmuje właściwe podejście: https://github.com/FooBarWidget/default_value_for
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-08-20 04:35:02
Oto rozwiązanie, które wykorzystałem, że byłem trochę zaskoczony, że nie zostało jeszcze dodane.
Są dwie części. Pierwsza część to ustawienie wartości domyślnej w rzeczywistej migracji, a druga część to dodanie walidacji w modelu zapewniającej, że obecność jest prawdziwa.
add_column :teams, :new_team_signature, :string, default: 'Welcome to the Team'
Więc zobaczysz tutaj, że wartość domyślna jest już ustawiona. Teraz w walidacji chcesz upewnić się, że zawsze istnieje wartość dla Ciągu, więc po prostu wykonaj
validates :new_team_signature, presence: true
To co zrobi to ustawi domyślna wartość dla Ciebie. (dla mnie mam" Welcome to the Team"), a potem pójdzie o krok dalej i zapewni, że zawsze jest wartość obecna dla tego obiektu.
Mam nadzieję, że to pomoże!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
2019-02-08 15:47:26
# db/schema.rb
create_table :store_listings, force: true do |t|
t.string :my_string, default: "original default"
end
StoreListing.new.my_string # => "original default"
# app/models/store_listing.rb
class StoreListing < ActiveRecord::Base
attribute :my_string, :string, default: "new default"
end
StoreListing.new.my_string # => "new default"
class Product < ActiveRecord::Base
attribute :my_default_proc, :datetime, default: -> { Time.now }
end
Product.new.my_default_proc # => 2015-05-30 11:04:48 -0600
sleep 1
Product.new.my_default_proc # => 2015-05-30 11:04:49 -0600
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
2019-12-15 19:29:55
Miałem podobne wyzwanie podczas pracy nad aplikacją Rails 6.
Oto Jak to rozwiązałem :
Mam Users
tabelę i Roles
tabelę. Tabela Users
należy do tabeli Roles
. Mam również modele Admin
i Student
, które dziedziczą z tabeli Users
.
Wymagane było ustawienie domyślnej wartości dla roli za każdym razem, gdy tworzony jest użytkownik, powiedzmy admin
rola, która ma id = 1
lub student
rola, która ma id = 2
.
class User::Admin < User
before_save :default_values
def default_values
# set role_id to '1' except if role_id is not empty
return self.role_id = '1' unless role_id.nil?
end
end
Oznacza to że przed utworzeniem/zapisem użytkownika admin
w bazie danych, {[16] } jest ustawiane jako domyślne 1
, jeśli nie jest puste.
return self.role_id = '1' unless role_id.nil?
Jest tym samym co:
return self.role_id = '1' unless self.role_id.nil?
I to samo co:
self.role_id = '1' if role_id.nil?
[18]}ale pierwszy jest czystszy i bardziej precyzyjny.
To wszystko.
Mam nadzieję, że to pomoże
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
2020-06-23 17:54:47
Używam tego od jakiegoś czasu.
# post.rb
class Post < ApplicationRecord
attribute :country, :string, default: 'ID'
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
2020-10-22 22:26:17
Użyj default_scope w rails 3
ActiveRecord zasłania różnicę między domyślnym zdefiniowaniem w bazie danych (schemacie) a domyślnym wykonaniem w aplikacji (modelu). Podczas inicjalizacji, analizuje schemat bazy danych i notuje wszelkie wartości domyślne określone tam. Później, podczas tworzenia obiektów, przypisuje te wartości domyślne określone w schemacie bez dotykania bazy danych.
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
2017-05-23 12:34:45
Z dokumentów api http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
Użyj metody before_validation
w swoim modelu, daje ona opcje tworzenia konkretnych inicjalizacji dla wywołań tworzenia i aktualizacji
np. w tym przykładzie (ponownie kod zaczerpnięty z przykładu api docs) pole numer jest inicjalizowane dla karty kredytowej. Możesz łatwo dostosować to, aby ustawić dowolne wartości
class CreditCard < ActiveRecord::Base
# Strip everything but digits, so the user can specify "555 234 34" or
# "5552-3434" or both will mean "55523434"
before_validation(:on => :create) do
self.number = number.gsub(%r[^0-9]/, "") if attribute_present?("number")
end
end
class Subscription < ActiveRecord::Base
before_create :record_signup
private
def record_signup
self.signed_up_on = Date.today
end
end
class Firm < ActiveRecord::Base
# Destroys the associated clients and people when the firm is destroyed
before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" }
before_destroy { |record| Client.destroy_all "client_of = #{record.id}" }
end
Zaskoczony, że jego nie został tu zasugerowany
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
2012-05-31 18:43:21