Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i18n lookup is not performed on nested models #48

Closed
sher opened this issue Sep 7, 2010 · 32 comments
Closed

i18n lookup is not performed on nested models #48

sher opened this issue Sep 7, 2010 · 32 comments
Labels

Comments

@sher
Copy link
Contributor

sher commented Sep 7, 2010

When using simple_fields_for helper (for a nested model) labels, hints etc. are not loaded from the locale.

@josevalim
Copy link
Contributor

Can you please give more information? How is your model? How is your simple_form_for call? Can you produce a failing test case?

@sher
Copy link
Contributor Author

sher commented Sep 7, 2010

The case is pretty simple, I think. There is a User model (devise model) which has_one UserProfile, and UserProfile belongs_to User. User "accepts_nested_attributes_for" UserProfile, and User has attr_accessible :profile.

The form looks like this:

<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= f.simple_fields_for :profile do |profile_form| %>
    <%= profile_form.firstname %>
  <% end %>
<% end %>

@josevalim
Copy link
Contributor

Err, except that your example would raise a NoMethodError? :) Do you mean profile_form.input :first_name?

Also, which keys are you expecting it to bring from I18n? Which ones is it bringing instead? The more information you give about an error the easier for it to get fixed.

@sher
Copy link
Contributor Author

sher commented Sep 7, 2010

Ok. My mistake. The form says <%= profile_form.input :firstname %>
And here is the excerpt from the locale file:

en:
  simple_form:
    labels:
      user_profile:
        firstname: "名"
      user:
        email: "メールアドレス"
        password: "パスワード"

In fact it does not bring any translation from locale yml.

@josevalim
Copy link
Contributor

Now I see your problem. This is done on purpose because when you have a nested attribute, simple form will look at simple_form.labels.user.user_profile.firstname, allowing you to have custom names for nested attributes.

If you want however to use the same firstname across all labels, one alternative is to change the human_attribute_name instead (using I18n API for Rails itself)

Please try to include the maximum information possible when reporting a bug or issue. Since this really helps us to understand what is happening.

@sher
Copy link
Contributor Author

sher commented Sep 7, 2010

Thanks and can you clarify something here? You should use a "model name" or "association name" as a key in locale when writing translations.

For example, if the association is like:

class User < ActiveRecord::Base
has_one :profile, :class_name => 'UserProfile'
end

then locale yml should look like this?

en:
simple_form:
labels:
user:
profile:
firstname: "Abra kadabra"

?

@josevalim
Copy link
Contributor

Let's look at the source code:

http://github.com/plataformatec/simple_form/blob/master/lib/simple_form/inputs/base.rb#L119

SimpleForm uses the object_name. You can retrieve it by doing <%= profile_form.object_name %> inside your fields_for and I believe it will return: "user_profile" instead of "user.profile". Not exactly what I said, but the result at the end is the same. Could you please confirm?

Notice I18n allows you to shortcut to translations, so you can eventually do this:

en:
  simple_form:
    labels:
      user_profile: :"simple_form.labels.profile"

This will link user_profile to the translations for labels profile.

@sher
Copy link
Contributor Author

sher commented Sep 7, 2010

<%= profile_form.object_name %>
returned
user[profile_attributes]

@josevalim
Copy link
Contributor

Ugh. It seems like a rails bug. Which Rails version are you using? object_name should return the underscore version. :(

@josevalim
Copy link
Contributor

Please use the human_attribute_name translation while I investigate this issue. :) Thanks!

@sher
Copy link
Contributor Author

sher commented Sep 7, 2010

I am using Rails 3 on ruby-1.9.2

@vesan
Copy link
Contributor

vesan commented Sep 23, 2010

I also have this problem with Rails 3 on Ruby 1.9.2 with simple_form 1.2.2. You can use this format and it works OK but the underscore version would be prettier :-) :

"user[profile]":
  firstname: "The Name"

@maduhaime
Copy link

Vesan : You can also redirect everithing nested to the original translation

# config/locale/models/address/fr.yml
fr:
  simple_form:
    hints:
      address:
        address_1: "Spécifiez votre numéro d'appartement au besoin"
        address_2: "Ce champ est facultatif"
        postal_code: "i.e. H0H0H0"
# config/locale/models/lead/fr.yml
fr:
  simple_form:
    hints:
      lead[address_attributes]: :"simple_form.hints.address"

@abravalheri
Copy link

I also have a similar problem with a "has_many" association, nevertheless I cannot use this solution because the object_name returned by Rails for this kind of association includes an index (so, redirecting for each index is not an alternative).

My test code is something like this:

class Contact < ActiveRecord::Base
  has_many :emails
  ...
end

...

<%= f.simple_fields_for :emails do |fields| %>
  <%= fields.object_name %>
  <%= render 'emails/fields', :f => fields %>
<% end %>

with the result:
contact[emails_attributes][0]

Someone has any idea about how to work with this?

I think even if it's a Rails bug, including the orginal model attributes in the translation lookup queue in the SimpleForm::Inputs::Base#translate method could help...

@jpzwarte
Copy link
Contributor

The reason object_name is the way it is, is because of the code here: https://github.com/rails/rails/blob/master/actionpack/lib/action_view/helpers/form_helper.rb#L1281

    def fields_for_with_nested_attributes(association_name, args, block)
      name = "#{object_name}[#{association_name}_attributes]"

The index get's appended a few lines below that:

output << fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block)

@josevalim
Copy link
Contributor

Yeah, I think SimpleForm will need to manipulate the object_name and get a readable version from it.

@jpzwarte
Copy link
Contributor

  # Extract the model names from the object_name mess.
  def model_names
    object_name.scan(/([a-zA-Z_]+)/).flatten.map{ |x| x.gsub('_attributes', '') }
  end

The above will return an array of model names. For example:

route[blocks_attributes][0][blocks_learning_object_attributes][1][asdf_attributes]

will result in: ["route", "blocks", "blocks_learning_object", "asdf"]

Not immediately obvious to me how to integrate this in the SimpleForm::Inputs::Base.translate method.

@rafaelfranca
Copy link
Collaborator

You can add a new lookup in the SimpleForm::Inputs::Base.translate method using this result.

@carlosantoniodasilva
Copy link
Member

Sounds a good idea, guess I'll give it a show when I find some time here. This keeps bothering me once in a while. Thanks.

@brewster1134
Copy link

so is the current status of this still to translate nested models, the format of
product[variations_attributes][0][shipping_profile_attributes]
is needed for when has_many is involved? im just setting generic translations, but its not the best solution.

@carlosantoniodasilva
Copy link
Member

Improve i18n lookup for nested models, closed by 25abdac

@carlosantoniodasilva
Copy link
Member

@jpzwarte I've used your scan method to improve the i18n lookup for nested models, it should be working fine now.

Could you guys please test with the master branch? Thanks.

@jpzwarte
Copy link
Contributor

Thanks a lot!

nodrog pushed a commit to vevoas/simple_form that referenced this issue Apr 28, 2011
@brodock
Copy link

brodock commented Dec 13, 2011

I've tried every sollution here, but still not working.
I'm using Rails 3.1 and a polymorphic association

class Produto < ActiveRecord::Base
  has_one :item, :as => :tipo, :dependent => :destroy
end


class Item < ActiveRecord::Base
  belongs_to :tipo, :polymorphic => true
end


simple_form:
  labels:
    produto:
      item:
        nome: "Anything"             

@caarlos0
Copy link

caarlos0 commented Sep 1, 2012

not working with rails 3.2 and ruby 1.9.3.

@nashby
Copy link
Collaborator

nashby commented Sep 1, 2012

@caarlos0 hi, what version of simple_form are you using? Could you push a simple app to github that reproduces this issue?

@nashby nashby reopened this Sep 1, 2012
@caarlos0
Copy link

caarlos0 commented Sep 2, 2012

version: 2.0.2

form is like this:

<%= simple_form_for(setup_birth(@birth), :html => {:class => 'form-horizontal'}) do |f| %>
    <div class="well">
        <legend> Dados do parto</legend>
            <%= f.input :bith_date, :input_html => { :class => 'datepicker' }, :as => :string, :disabled => !@birth.new_record? %>
            <%= f.input :cow, :collection => Animal.inseminated_cows_collected, :disabled => !@birth.new_record?  %>
            <%= f.input :obs, :input_html => { :cols => 50, :rows => 10, :style => "width: 400px" } %>
            <% unless @birth.new_record? %>
                <%= link_to "Editar filhote", edit_animal_path(@birth.child), :class => "btn" unless @birth.child.nil? %>
            <% end %>   
    </div>
    <% if @birth.new_record? %>
    <div class="well">
        <legend>Dados do filhote</legend>
            <%= f.simple_fields_for :child_attributes do |ff| %>
                <%= ff.input :earring %>
                <%= ff.input :name %>
                <%= ff.input :animal_type_id, :collection => AnimalType.all.collect { |t| [t.desc, t.id]} %>
            <% end %>
        </div>
    <% end %>
  <%= f.button :submit %>
<% end %>

pt.yml like this:

 birth:
        bith_date: 'Data Parto'
        cow: 'Mãe'
        obs: "Observação"
        child:
          earring: "Brinco"
          name: "Nome"
          animal_type_id: "Tipo de Animal"

I tried several things... nothing works.

@nashby
Copy link
Collaborator

nashby commented Sep 2, 2012

@caarlos0 hrm, I think here

<%= f.simple_fields_for :child_attributes do |ff| %>

you should use

<%= f.simple_fields_for :child do |ff| %>

no?

@caarlos0
Copy link

caarlos0 commented Sep 2, 2012

ooops, my mistake.
Sorry.

Hey, maybe you can add something about this in docs, huh?

Thanks anyway.
cheers

@nashby
Copy link
Collaborator

nashby commented Sep 2, 2012

So does it work now? If so I don't think we should add something to SimpleForm's docs as fields_for is a Rails's feature and it has a lot of documentation on it http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for

@caarlos0
Copy link

caarlos0 commented Sep 2, 2012

hmm.. yeah, that's right.. sorry, I'm new on ruby/rails, when I research for nested forms I didn't find this documentations..

so, thank you again for the link :)

@nashby
Copy link
Collaborator

nashby commented Sep 3, 2012

no problem :)

@nashby nashby closed this as completed Sep 3, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests