Rails i18n.default_locale and date format ... doesn't seem to be acting like a default - ruby-on-rails-3

I want Rails (3.2) to use the American date format 03/14/2012 unless I say otherwise.
I have the I18n gem installed, downloaded (and modified) the config/locales/en-US.yml file to have the default format as default: ! '%m/%d/%Y', set my application.rb default locale as config.i18n.default_locale = "en-US", and restarted.
When dates are displayed (e.g. a simple view) they still have the format 2012-03-14. If I use the I18n.l method, the date displays as desired, 03/14/2012. So localization is working through the I18n class.
I guess I was expecting the meaning of "default" to be, "this is the one to use if you're not otherwise told to localize or translate." Apparently I expected wrong :-)
So further digging revealed I could change the defaults for date and time in an initializer, such as config/initializers/date_formats.rb, e.g.
Date::DATE_FORMATS[:default]="%m/%d/%Y"
Time::DATE_FORMATS[:default]="%m/%d/%Y %H:%M"
This appears to do what I want. Several alarming posts suggests that this will screw up how dates are stored in the database, but my tests (using PostgreSQL) suggest that this is not a problem.
So (rant) why the heck shouldn't all apps observe the default locale without wrapping every date on the face of the earth with l and t helpers?
And (actual question) will I cause permanent harm to myself or others by changing the default date and time formats for my application in an initializer?

I had the same problem and this gem helped me https://github.com/jeremyevans/ruby-american_date
Just add it to your Gemfile, no settings needed

Related

How to get UTC TimeZone DisplayName .NET 4.0?

I set a winforms combobox with the time zones DisplayName:
var zoneList = TimeZoneInfo
.GetSystemTimeZones()
.Where(z => z.BaseUtcOffset.Minutes == 0)
.Select(z => z.DisplayName);
It shows a list like this:
...
(UTC-01:00) Azores
(UTC-01:00) Cabo Verde Is.
(UTC) Casablanca
(UTC) Co-ordinated Universal Time
(UTC) Dublin, Edinburgh, Lisbon, London
(UTC) Monrovia, Reykjavik
(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
...
I want to sent the default item to (UTC) Co-ordinated Universal Time. However, TimeZoneInfo.Utc.DisplayName returns UTC. It is unusual because the upper enumeration shows different DisplayName.
TimeZoneInfo.FindSystemTimeZoneById("UTC") also returns "UTC".
TimeZoneInfo.FindSystemTimeZoneById("(UTC) Co-ordinated Universal Time") and TimeZoneInfo.FindSystemTimeZoneById("Co-ordinated Universal Time") do not work.
How to get the localized string that corresponds to shown in the enumeration (UTC) Co-ordinated Universal Time?
The only solution I can figure out is to store the string "(UTC) Co-ordinated Universal Time", but I'm afraid the upper list may change in different localization.
A few things:
The DisplayName is not the ID. Only the values returned by the Id property are suitable for use with the FindSystemTimeZoneById method.
For your dropdown list, you should show the DisplayName, but you should store only the Id.
The DisplayName, StandardName and DaylightName properties are localized by the operating system, not by the globalization features of the .NET Framework.
The IDs will always be in English. They will never change for localization.
You should never show the IDs to the end-user or interpret them in any particular way. There are many different conflicting conventions used, and some that are just made up. See the section on Windows time zones in the timezone tag wiki for some examples.
"Coordinated" is a single non-hyphenated word. These are correct in Windows, so I think you must have added the hyphen yourself.
Recognize that the offsets shown in the display names are just the base offsets. They do not indicate whether or not the time zone adjusts for daylight saving time or not. Nor do the offsets in this list change when daylight saving time is in effect.
You are correct that TimeZoneInfo.Utc.DisplayName == "UTC", and so does TimeZoneInfo.FindSystemTimeZoneById("UTC").DisplayName. However, the UTC entry returned by TimeZoneInfo.GetSystemTimeZones() has the full form of the display name: "(UTC) Coordinated Universal Time". Therefore, if you're displaying a dropdown list by enumerating the results from TimeZoneInfo.GetSystemTimeZones(), then you can just use the results as-is.
But if you want to get that display name directly, you will either have to do this:
string s = TimeZoneInfo.GetSystemTimeZones().First(x => x.Id == "UTC").DisplayName;
Or, this:
string key = #"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\UTC";
string s = Registry.GetValue(key, "Display", null) as string;
Again, remember that all localization of time zone display names is done by the operating system. Therefore, this approach works fine for Windows desktop applications, but doesn't make a whole lot of sense for web apps. Also, if your application supports multiple languages internally, you won't be able to rely on .NET Globalization for any time zone display names. In that scenario, you will need to provide your own source of display names, perhaps in a .resx file, or you can look into using my TimeZoneNames library.
Hmm, I found the answer by printing the time zone's Id.
The desired string is printed with:
TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); // Wrong
Edit:
As Matt Johnson noted, the above code shows the London time zone.
Here is another try:
TimeZoneInfo.GetSystemTimeZones().First(t=>t.Id=="UTC").DisplayName

Dashes in property name not getting NoMethodError

I'm using the Linkedin gem to pull profile information for RoR 3.
Gem: https://github.com/pengwynn/linkedin
API Doc: https://developer.linkedin.com/documents/profile-fields#positions
Everything works except when I get to a property with a dash in the name.
<%=position.title %> displays correctly but<%= position.start-date %> return a NoMethodError in Users#show - undefined method start.
I've tried different operations like "startDate", "start_date", quotes around "start-date" but none have worked.
Is there a proper way to escape the dash/hyphen in the property name?
The expression in your ERB will be parsed as subtracting the value of the date variable from the result of a call to the start() method of the position object. Hyphens aren't valid in identifiers within Ruby.
I'm not familiar enough with the LinkedIn gem to suggest a solution, except to say that since it's based on an XML API, you should look for a way to manually pull data out of a tag pair. Most similar gems offer such a method. Also, this is a great case for using IRB as an exploratory tool: fire up an IRB session and see what happens when you call position.methods, after properly creating the position variable of course. My guess would be that you'll see something in that list which suggests an answer.
Looks like it returns a Hashie::Mash which converts keys, with a few extra rules:
https://github.com/pengwynn/linkedin/blob/master/lib/linked_in/mash.rb
You said you'd already tried position.start_date right? That should work. But if not, have you tried position['start-date'] or position['start_date'] one of those two should also work, since it's a Mash.

How to change Unix Timestamp to Human Date in rails 3

I've seen a couple of posts doing the reverse for mysql, but I'm looking for a way to change a unix timestamp to a human readable date (ideally one I can change the format of) and I haven't been able to find anything so far.
I'm storing a date pulled from an XML feed, via NokoGiri (in Rails 3.1.1) as part of a hash:
'date' => i.xpath('#unix-timestamp')
which gets the number fine, but how the devil do you make this DD-MM-YYYY to be put in one of my views?
I've tried Time.at( (i.xpath('#unix-timestamp') ) to no avail; I just get the error 'can't convert Nokogiri::XML::NodeSet into an exact number' and now I've hit a wall
Much gratitude for any help!
Time.at is definitely a call that should work to convert from epoch time to a ruby Time object (see here for an example). So it seems like you need to work on converting your XML result into something more usable. I think you want to try using NodeSet#text to get a string output, then converting that to an integer:
Time.at(i.xpath('#unix-timestamp').text.to_i)
There's a decent but basic tutorial for NokoGiri in the Engineyard blog
You can use like : DateTime.strptime("1373210218",'%s')
and also Time.at(1373210218).strftime("%B %e, %Y at %I:%M %p")

Systematic way to upgrade from attachment_fu to carrierwave?

I'm working on upgrading an app to Rails 3, and attachment_fu is broken so I'm moving to carrierwave. Is there a systematic process that I can go through to upgrade from attachment_fu to carrierwave? Or a tutorial for it? Right now, I'm more interested in getting everything on the database end right. I'm using the filesystem store option for attachment_fu and carrierwave.
I've found a module, UploaderFu from http://ruby.simapse.com/2011/03/migrate-attachmentfu-to-carrierwave.html that tells carrierwave to use the same directories and filenames as attachment_fu. But it's not the entire answer, just part of it.
For example, in the db, I have a UserImage model, with :filename, :content_type, :size, :width, :height, and :user_id attributes. I added a :user_avatar column, and the following to my model
attr_accessible :user_avatar
mount_uploader :user_avatar, UserAvatarUploader
What exactly gets stored in :user_avatar. Is it just the filename? or something else? Do I just need to write a migration to move the data in :filename (stored like "hello_world.png") to :user_avatar? If that's the case I should just use the original :filename instead of creating a :user_avatar column, right?
The column you mount the uploader on is supposed to store an "identifier" for the uploaded file. By default it's just the filename, but you can override it to be almost anything apart from the ID of the record (because you can't know what that is until after saving).
To override: in your uploader class, add this definition :
def identifier
# This is what gets put in the database column!
model.created_on
end
In this example I've used the created_on attribute from the model. If you want to create your own storage mechanism then you need to be able to uniquely identify files by this identifier so be careful what you choose.
I would suggest renaming the column so it describes the file that's being uploaded (like in the carrierwave example). Then you can always change the identifier from filename to something else later.

Ruby on Rails 3: rails_admin + puret?

Did someone try to integrate puret into rails_admin? I can't make a language switch to edit different translations :(
Changing I18n.locale forces whole rails_admin to use specified locale.
Now I got the solution. The two can work together well. In short:
Delete the pureted column(s) in your model
If you have the column pureted still in your model, rails form helper will bypass puret. That is, if a model called Post has a field called contents to be i18ned, the table posts SHOULD NOT have the column contents.
Actually we should use globalize3 instead. With this you do not need to remove the original column. And puret doens't support nested attributes assignment. globalize3 works very well.