Looking for labels for belongs_to causes problems. undefined method `<<' for {:name=>"Author Name"}:Hash #584

Closed
asanghi opened this Issue May 31, 2011 · 5 comments

Comments

Projects
None yet
2 participants
Contributor

asanghi commented May 31, 2011

My form has a belongs_to collection dropdown.

    class Author < AR::Base
      has_many :posts
    end
    class Post < AR::Base
      belongs_to :author
    end

    <%= form_for(@post) do |f| %>
      <%= f.input(:author, :collection => Author.all) %>
    <% end %>

I expect the label to come out to be Author.

My config/en/locale.yml looks like this

    en:
      formtastic:
        author:
          name: Author's Name

This is the error received:
undefined method<<' for {:name=>"Author Name"}:Hash`

I think the problem is in how i18n does the lookups in the locale file and what keys we provide for lookup.

The call to I18n.translate ends up being:

::I18n.translate("post.new.author",{:default=>[:"post.author", :author, ""], :scope=>[:formtastic, :labels]})
The above returns {:name=>"Author Name"}, a hash which is NOT nil and unsuitable for string concat later in Formtastic.

It would be normal in my opinion to have a key for "author" in the locale file as it is a proper model. We're also using the model as a belongs_to relationship in Post. Should this be raised in i18n? I'm using version 0.5.0 of the i18n gem.

Using formtastic from git master on Rails 3.0.7

Contributor

asanghi commented May 31, 2011

The workaround is to explicitly put the author : Author key-value pair under post in the locale file.

Contributor

asanghi commented May 31, 2011

And I saw the same problem in i18n 0.6.0 as well, so the problem would persist on Rails 3.1.0 as well.

Owner

justinfrench commented May 31, 2011

I noticed similar stuff when trying to upgrade Formtastic's tests to work with 3.1. Upon looking at your example, it almost feels like we've got a bug. Here's the scopes from Formtastic::I18n:

 SCOPES = [
    '%{model}.%{nested_model}.%{action}.%{attribute}',
    '%{model}.%{action}.%{attribute}',
    '%{model}.%{nested_model}.%{attribute}',
    '%{model}.%{attribute}',
    '%{nested_model}.%{attribute}',
    '%{attribute}'
  ]

So I think what's happening is that the label for the :author input is trying en.formtastic.labels.post.new.author, falling back to en.formtastic.labels.post.author, and then finally en.formtastic.labels.author. I'm a little bit puzzled why the labels part of the scope, but we can come back to that.

The key here is that for a label, author is an attribute, so the problem with the above scoping is that you're also specifying author as a model with attributes (hence the hash).

I'm wondering if you could try adding a labels scope to see if that clears up the problem:

en:
  formtastic:
    labels:
      author: Author's Name
    author:
      name: Author's Name

Perhaps we can also catch this error (was it raised in Formtastic or in i18n?) and handle it better. I can't see any specific changes in i18n 0.6.0 to cause this, but I'm not an expert.

Contributor

asanghi commented May 31, 2011

I think i made a mistake in posting the fragment from my locale file. I DO indeed have the :labels scope throughout.
I need to override attributes from author but not really from post.

When I did NOT have the post keys, i got an error as specified in the title.

en:
  formtastic:
    labels:
      author:
        name: Author Name
      post:
        author: Author # Forced to add this to prevent i18n lookup falling back on author above

The problem was raised within formtastic in labelling.rb when concatenating the label with required label. label returns a hash and required returns a string but they cant be joined. Method label_text

I think in localized_string we're checking for return value being blank?, but I think we should consider it "not fetched" if we get anything but a "non-blank string" from i18n.

I spoke to @svenfuchs about i18n returning hashes and he schooled me that it was indeed a functionality of the i18n gem to return subtrees if so fetched. This helps in saving N+1 queries when you do indeed need to get all keys/values from the locale file. So, i18n is behaving itself as specified.

Contributor

asanghi commented May 31, 2011

Somewhat similar problem seems to have been raised here #293 (#293) , but the solution in my mind could have been better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment