There are several issues with each of the available methods, but I believe that defining an after_initialize
callback is the way to go for the following reasons:
default_scope
will initialize values for new models, but then that will become the scope on which you find the model. If you just want to initialize some numbers to 0 then this is not what you want.
- Defining defaults in your migration also works part of the time... As has already been mentioned this will not work when you just call Model.new.
- Overriding
initialize
can work, but don't forget to call super
!
- Using a plugin like phusion's is getting a bit ridiculous. This is ruby, do we really need a plugin just to initialize some default values?
- Overriding
after_initialize
is deprecated as of Rails 3. When I override after_initialize
in rails 3.0.3 I get the following warning in the console:
DEPRECATION WARNING: Base#after_initialize has been deprecated, please use Base.after_initialize :method instead. (called from /Users/me/myapp/app/models/my_model:15)
Therefore I'd say write an after_initialize
callback, which lets you default attributes in addition to letting you set defaults on associations like so:
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
Now you have just one place to look for initialization of your models. I'm using this method until someone comes up with a better one.
Caveats:
For boolean fields do:
self.bool_field = true if self.bool_field.nil?
See Paul Russell's comment on this answer for more details
If you're only selecting a subset of columns for a model (ie; using select
in a query like Person.select(:firstname, :lastname).all
) you will get a MissingAttributeError
if your init
method accesses a column that hasn't been included in the select
clause. You can guard against this case like so:
self.number ||= 0.0 if self.has_attribute? :number
and for a boolean column...
self.bool_field = true if (self.has_attribute? :bool_value) && self.bool_field.nil?
Also note that the syntax is different prior to Rails 3.2 (see Cliff Darling's comment below)
I ran into the issue after we migrated our in-house Exchange server to Office 365.
The AD Connect tool is working as designed. The Primary email attribute in the local Active Directory changed, so AD Connect pushed the change to Office 365. To make the correct email address primary, you will need to access the Attribute Editor tab in Active Directory Users and Computers. If you don’t see that tab for your user objects, click on the “View” menu at the top of Active Directory Users and Computers (ADUC) and then click on “Advanced”.*
Then,
- Open the properties of the user object you need to change in ADUC.
Click on the Attributes tab.
Find the proxyAddresses value and click edit.
TYPE IN THE ADDRESS WITH A CAPITAL SMTP (this is what makes it primary)
For example
SMTP: jerry.seinfeld@yaddayadda.com
The change will take effect at next AD Connect Sync (auto or manual).
*note: The Attributes tab won't appear using the Remote Server Administration Tools. You'll need to login to the Domain Controller and use ADUC from there. Alternatively, you can use ADSI Edit remote tools to change the primary email address for a user.
See below for ADSI Edit steps.
Click Start, click Run, type ADSIEdit.msc, and then click OK.
Right-click ADSI Edit, select Connect to, and then click OK to load the domain partition.
In the navigation pane, locate the user object that you want to modify, right-click it, and then click Properties.
In the Attributes list, click the proxyAddresses attribute, and then click Edit.
In the Value to add field, enter the appropriate SMTP address, and then click Add.
Note The primary SMTP address value for the user object should be prepended by an uppercase "SMTP:" designator for it to be formatted correctly for the proxyAddresses attribute.
For example:
"SMTP:username@contoso.com" is an acceptable value.
"username@contoso.com" and "smtp:username@contoso.com" are not acceptable values.
Click OK two times, and then exit ADSI Edit.
The ADSI Edit instructions taken from the TechNet article https://blogs.technet.microsoft.com/hot/2012/06/25/how-to-use-smtp-matching-to-match-on-premises-user-accounts-to-office-365-user-accounts-for-directory-synchronization/
Best Answer
The answer is "use () and defaults"
http://guides.rubyonrails.org/routing.html#dynamic-segments and http://guides.rubyonrails.org/routing.html#defining-defaults