RAILS: undefined method `map' caused by missing I18n translation - ruby-on-rails

I changed the format for a datetime field in a RAILS 4 new.html.erb from :string to datetime and it caused error as below:
undefined method `map' for "translation missing: zh-CN.date.order":String
The view code causing the error above is:
<%= f.input :start_time, :label => t("Start Time"), required: true, :as => :datetime, :ampm => true, :minute_step => 10, :start_year => Date.today.year - 1, :end_year => Date.today.year + 1, :format => 'YYYY/MM/DD/HH/MM', :use_month_numbers => true, :include_blank => true %>
The RAILS source code blows up is in actionview/helpers/date_helper.rb:
def translated_date_order
date_order = I18n.translate(:'date.order', :locale => #options[:locale], :default => [])
date_order = date_order.map { |element| element.to_sym } #<<<<<<===blows up
forbidden_elements = date_order - [:year, :month, :day]
if forbidden_elements.any?
raise StandardError,
"#{#options[:locale]}.date.order only accepts :year, :month and :day"
end
date_order
end
I do have a file zh-CN.yml under /config/locale/ and it is providing translations for others except this one.
UPDATE portion of zh-CN.yml:
zh-CN:
#maint_recordx
Mfg Batches : '订单批次一览'
New Batch : '新批次'
Update Batch : '更新批次'
Edit Batch : '更新批次'
...........

After being bitten by this same error, I found that Rails sets the following key:
:'date.order'
to the value:
["year", "month", "day"]
for the default :en locale
You can confirm this by running the following snippet in rails console for a default rails install:
date_order = I18n.translate(:'date.order', :locale => :en, :default => [])
Notice I just switched #options[:locale] for the default :en value
The rails helper you reference, expects an array for the date_order value, and will blow up if it doesn't get one.
In my case, I improperly configured the I18n::Backend::ActiveRecord gem and therefore it interfered with the value being returned by I18n. You probably have a similar issue preventing the correct value for the :'date.order' key being returned.
EDIT:
In order to fix this, you should probably just need to install the gem 'rails-i18n'. It will handle returning the correct date formats for supported locales. In my case I had a custom configuration in my es.yml locale file that returned an incorrect date format.

Bingo !!! You just have to add the missing key translation to your local translations.
I solved it by adding
en:
date:
order: ["day", "month", "year"]
to
config/locales/en.yml

Related

Entering in large dollar values into rails money object

I have built an application running rails 4.1 and ruby 1.9.3 that uses the money-rails gem. I'm encountering an issue when I input large dollar values into form fields and save them to my PG database. The error is the following:
PG::NumericValueOutOfRange: ERROR: value "9900000000" is out of range for type integer
The PG docs show the max value of an integer being +2147483647. I would like to be able to use the money-rails gem but be able to enter larger numbers.
As far as a solution goes, I understand that the column type in PG should be a bigint, however I'm not how to enable money-rails to support storing numbers as bigint instead of integers.
Here in the money-rails README it shows that you can configure it to use other data types:
# Default ActiveRecord migration configuration values for columns:
#
# config.amount_column = { prefix: '', # column name prefix
# postfix: '_cents', # column name postfix
# column_name: nil, # full column name (overrides prefix, postfix and accessor name)
# type: :integer, # column type
# present: true, # column will be created
# null: false, # other options will be treated as column options
# default: 0
# }
Notice there's a type: :integer option. Try changing that to :bigint.
I had similar question recently (with ruby 2.0 & rails 4.1). The only thing that was required is creating migration to support 8-byte integers, i.e. bigint:
change_column :order_items, :unit_price_cents, :integer, :limit => 8
And it just worked. I my case I needed to support also 4 decimals, so I had to recreate USD currency as follows:
MoneyRails.configure do |config|
config.register_currency = {
:priority => 1,
:iso_code => "USD",
:iso_numeric => "840",
:name => "United States Dollar with subunit of 4 digits",
:symbol => "$",
:symbol_first => true,
:subunit => "Subcent",
:subunit_to_unit => 10000,
:separator => ".",
:delimiter => ","
}
end

rails check_box value using translation I18n

just wondering how I should do internationalization in rails when using a checkbox in a normal (very simple) form;
This is what I tried:
view/form file:
<%= f.check_box :do_you_agree, {}, t('submissions.yes'), t('submissions.no') %>
<%= f.check_box :do_you_agree, {}, I18n.t('submissions.yes'), I18n.t('submissions.no') %>
<%= f.check_box :do_you_agree, {}, "#{t('submissions.yes')}", "#{t('submissions.no')}" %>
...and all them return:
translation_missing in HTML.
When I use :
<%= f.check_box :do_you_agree, {}, 'NO', 'YES' %>
...everything is ok!
The YML file is ok. Many thanks.
In your config/application.rb you must have the line config.i18n.default_locale = :es (:es for spanish, as an example)
And the yml must be like this:
es:
submissions:
'yes': Si
'no': No
Edit: Make the yes/no keys explicit strings. And it will works.
Why? Because Rails does yaml conversion with psych gem. And psych return true and false with all those values (see the links).
Then, if you define a locales this way:
es:
submissions:
yes: Si
no: No
at the rails console you get:
irb> I18n.t('submissions')
=> {true=>"Si",false=>"No"}
irb> I18n.t('submissions')[true]
=> "Si"
irb> I18n.t('submissions.true')
=> "translation missing: es.submissions.true"

Carrierwave mongoid upload. Getting an undefined method `empty?' for #<ActionDispatch::Http::UploadedFile:0x00000109968c50>

I'm trying to upload an image file to my rails server, but I keep hitting a wall.
This is my form themed_controller/new ,
= form_for(#campaign, validate: true, :html => {:multipart => true}) do
.form-group
%label.col-sm-3.control-label
Campaign Name
.col-sm-6
%input#title.form-input{ name: "#campaign[campaign_title]", placeholder: "Campaign Title", required: "", type: "text", value: ""}/
.form-group
%label.col-sm-3.control-label
Campaign Description
.col-sm-6
%textarea.form-input{ name: "#campaign[campaign_description]", placeholder: "Campaign Description", required: "", value: ""}
.form-group
%label.col-sm-3.control-label
Pick stories
.col-sm-6
%select#themed_campaign_live_story_ids{name: "#campaign[live_story_ids][]", :multiple => true, :required=> true, value: []}
-# = f.select 'live_story_ids[]', [], :multiple => true
#date-range
.form-group#valid-from
%label.col-sm-3.control-label
Campaign runs from
.col-sm-6
%input.form-input#themed_campaign_valid_from{ name: "#campaign[valid_from]",:class => 'jquery-ui-date valid-from', :data => {:provide =>"datepicker", :behaviour => "datepicker"}, required: "", type: "text", value: ""}/
.form-group#valid-till
%label.col-sm-3.control-label
Campaign runs till
.col-sm-6
%input.form-input#themed_campaign_valid_till{ name: "#campaign[valid_till]",:class => 'jquery-ui-date valid-till', :data => {:provide =>"datepicker", :behaviour => "datepicker"}, required: "", type: "text", value: ""}/
.form-group#valid-till
%label.col-sm-3.control-label
Upload cover (1280x350)
.col-sm-6
-#upload-image.btn.btn-medium.btn-green{ :data => {:url => "/campaign/upload"} }
#upload-image
%input#image_media{name: "#campaign[cover]", type: "file"}/
.form-group
.col-sm-offset-3.col-sm-6
%button.form-button.btn-large.btn-green.btn#campaign-submit{type: "submit"}
Set up Campaign
And this is my create method
def create
campaign = params[:#campaign]
campaign['added_by_email'] = current_user.email
#campaign = ThemedCampaign.create(campaign)
if #campaign.save
img_attr = params[:#campaign]['cover']
image = Campaign.new img_attr
#campaign.cover = image
Resque.enqueue(ImageQueue,image.id)
#render :json => image.to_jq_upload.to_json
end
redirect_to '/admin/themecampaign'
end
I have created a seperate uploader for this,
# encoding: utf-8
class CampaignUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
before :cache, :save_original_filename
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg png)
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/campaigns/#{model.id}/"
end
end
And this is my campaign modal, which hold the image
class Campaign
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Paranoia
include Rails.application.routes.url_helpers
mount_uploader :cover, CampaignUploader
end
Now when I upload the form I keep getting an undefined methodempty?' for #
> NoMethodError - undefined method `empty?' for
> #<ActionDispatch::Http::UploadedFile:0x00000109968c50>: () Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/bundler/gems/mongoid-bc72426681d5/lib/mongoid/attributes/processing.rb:21:in
> `process_attributes' ()
> Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/bundler/gems/mongoid-bc72426681d5/lib/mongoid/document.rb:111:in `block in initialize' ()
> Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/bundler/gems/mongoid-bc72426681d5/lib/mongoid/threaded/lifecycle.rb:84:in
> `_building' ()
> Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/bundler/gems/mongoid-bc72426681d5/lib/mongoid/document.rb:105:in `initialize' actionpack (4.0.2)
> lib/action_dispatch/routing/url_for.rb:104:in `initialize'
> app/controllers/themed_campaign_controller.rb:57:in `new'
> app/controllers/themed_campaign_controller.rb:57:in `create'
Essentially, this blows up while trying to call Campaign.new with the image attributes. I thought the image field was nil but when I inspected the img_attr from the server, I noticed the uploaded file was present and the temp field was corretly pointing to a local copy.
When I dug deeper, I noticed the the cover filed in my themed_controller was invalid.
MOPED: 127.0.0.1:27017 INSERT database=mangoweb_development collection=themed_campaigns
documents=[{"_id"=>BSON::ObjectId('53ba605c5661731da8060000'),
"campaign_title"=>"Test campaign", "campaign_description"=>"Test
campaign desciption", "live_story_ids"=>["53a9b3e5566173146e030000",
"5343eafc5661731195030000", "5343eacc566173117f030000",
"5343eadf5661731189030000"], "valid_from"=>2014-07-07 00:00:00 UTC,
"valid_till"=>2014-07-22 00:00:00 UTC,
"cover"=>"#",
"added_by_email"=>"xxxxxxxxx",
"campaign_sane_title"=>"Test-campaign", "updated_at"=>2014-07-07
08:54:52 UTC, "created_at"=>2014-07-07 08:54:52 UTC}] flags=[]
COMMAND database=mangoweb_development command={:getlasterror=>1, :w=>1}
runtime: 11.9600ms
#
What am I doing wrong here?Why is the value of cover is a String version of the uploaded Object reference, instead of the file values, and why the Image not getting created?
I've been over this issue for the last 2 days, and have looked at various references. I know, I must be doing something very silly, but I'm not able to get it.
Please help me with this issue. Thanks in advance.
You can use form instance object to easily handle this
Change
form_for(#campaign, validate: true, :html => {:multipart => true}) do
to
form_for(#campaign, validate: true, :html => {:multipart => true}) do |f|
and use f while referencing the form fields
%textarea.form-input{ name: "#campaign[campaign_description]", placeholder: "Campaign Description", required: "", value: ""}
should be changed to
f.text_area :campaign_description, placeholder: "Campaign Description", required: "", value: ""
and for the file field
f.file_field :cover
Let me know if that works

Any rails code inside haml tags generates blank/empty characters inside browsers html tags

Whenever a rails variable equals nil (or actually whenever i use rails code (see 3rd code sample)) i get a string of empty characters in my html.
new.html.haml
%h1.editable.editable_title_field{:contenteditable => 'true', :placeholder => "title"}
= #post_title //#post_title.present? returns false
%h4.editable.editable_subtitle_field{:contenteditable => 'true', :placeholder => "subtitle"}
= #post.subtitle
%p.editable.editable_intro_field{:contenteditable => 'true', :placeholder => "intro"}
= #post.intro
this results in:
i checked, and even:
%h1.editable.editable_title_field{:contenteditable => 'true', :placeholder => "title"}
- #post_title
and:
%h1.editable.editable_title_field{:contenteditable => 'true', :placeholder => "title"}
-
ends up the same as in attached image
because of those empty characters :empty css selector treats the element as if it was not empty and doesnt append content specified in :before
how do i get rid of those empty characters inside my html tags?
EDIT
screencast of this behavior:
http://quick.as/jqlaiorq
Try it with a < on the end of the %h1 line:
%h1.editable.editable_title_field{:contenteditable => 'true', :placeholder => "title"}<
= #post_title
See the whitespace removal info in the HAML documentation.

Changing the currency format for product prices within Spree

I'm upgrading spree to from spree 1.0 to 1.3 and get stuck with the new currency options.
I want to render prices as: '€ 100' but instead get '€100'. How do I get a space between the unit and the value?
Note: Changing the locale file doesn't work, since it uses the money gem.
There are a bunch of ways to do this. The easiest would probably be to re-register the Euro currency with a different symbol.
Put the following in an initializer:
# encoding: utf-8
Money::Currency.register({
:priority => 1,
:iso_code => "EUR",
:iso_numeric => "978",
:name => "Euro",
:symbol => "€ ",
:subunit => "Cent",
:subunit_to_unit => 100,
:separator => ".",
:delimiter => ","
})
A rails console now reports:
> Spree::Money.new(100, currency: 'EUR')
=> € 100.00
I did the following in my config/initializers/spree.rb to inject a different symbol:
Money::Currency.table[:chf].merge!(symbol: 'CHF ')
This way the currencies aren't going to mix up.
Thanks a lot.
In my case, used the following to change the symbol generated by the to_html method, in case anyone has the same problem.
# encoding: utf-8
Money::Currency.register({
:priority => 1,
:iso_code => "CLP",
:iso_numeric => "152",
:name => "Chilean Peso",
:symbol => "$",
:subunit => "Peso",
:subunit_to_unit => 1,
:separator => ",",
:delimiter => ".",
html_entity: "$"
})
I solved the problem with the following in an initializer, e.g. config/initializers/currency_formatting.rb:
# Display prices with a space between symbol and number:
Spree::Money.default_formatting_rules[:symbol_before_without_space] = false
This hooks into the formatting rules found in Spree::Money, which can control all the formatting Options of the Money Gem, including the one placing a space between the symbol and the number. This has the advantage over the other solutions presented here that it works with all currencies at once.
Okay, this was pretty easy. As of gem version money(6.16.0).
In Spree intializer spree.rb Recommended way:
Spree.config do |config|
...
...
# Below is deprecated
Spree::Money.default_formatting_rules[:symbol_before_without_space] = false
# Instead try this
Spree::Money.default_formatting_rules[:format] = '%u %n'
end

Resources