2016-01-01 3 views
0

Я пытаюсь сделать приложение в Rails 4. Я использую простую форму для форм и country_select gem для списков стран.Rails 4 - Country Select & Simple Form

У меня есть модель адреса, которая включает в себя этот метод:

def country_name 
    self.country = ISO3166::Country[country] 
    country.translations[I18n.locale.to_s] || country.name 
    end 

При попытке сохранить новый адрес, я получаю эту ошибку:

undefined method `translations' for "Australia":String 

Может кто-нибудь увидеть, что случилось с этим определение метода?

Если я изменю свою точку зрения на:

<% if @profile.addresses.any? %> 
     <%= @profile.addresses.first.country.titlecase %> 
    <% else %> 
     <span class="profileeditlink"> 
      <%= link_to "Add your location", new_address_path %> 
     </span> 
    <% end %> 

Тогда запись дисплеев - но вместо того, чтобы АС Австралии (который является то, что метод в модели адреса обеспечивает).

Адрес таблице:

create_table "addresses", force: :cascade do |t| 
    t.string "unit" 
    t.string "building" 
    t.string "street_number" 
    t.string "street" 
    t.string "city" 
    t.string "region" 
    t.string "zip" 
    t.string "country" 
    t.boolean "main_address" 
    t.boolean "project_offsite" 
    t.string "time_zone" 
    t.float "latitude" 
    t.float "longitude" 
    t.integer "addressable_id" 
    t.integer "addressable_type" 
    t.datetime "created_at",  null: false 
    t.datetime "updated_at",  null: false 
    end 

    add_index "addresses", ["addressable_type", "addressable_id"], name: "index_addresses_on_addressable_type_and_addressable_id", unique: true, using: :btree 

ПРИНИМАТЬ JAEHYEN'S внушения,

Я изменил мой метод название страны в модели адреса в:

def country_name 
    # self.country = ISO3166::Country(country) 
    # country.translations[I18n.locale.to_s] || country.name 
    iso_country = ISO3166::Country.find_by_name[country] # `country` should be name like 'Australia' 
    iso_country.translations[I18n.locale.to_s] || iso_country.name 
    end 

Я получаю эту ошибку:

undefined method `translations' for nil:NilClass 

ДРУГАЯ ПОПЫТКА:

Я нашел этот ресурс: http://www.scriptscoop.net/t/4ee6d5ef4577/displaying-countries-using-country-select-gem-in-rails-4.html

Я попытался изменить свою форму ввода в:

 <%= f.country_select :country, priority: [ "Australia", "New Zealand", "United Kingdom" ] %> 

Это еще раз показывает код страны вместо названия страны. Я застрял.

ДРУГАЯ ПОПЫТКА

Я нашел этот пост: Rails Simple_Form: How to show long name of the country

Ответ на этот пост предполагает определение COUNTRY_NAME как:

def country_name 
    country = ISO3166::Country[country_code] 
    country.translations[I18n.locale.to_s] || country.name 
    end 

Это немного отличается от моих предыдущих попыток, однако, когда Я пробую это, я получаю эту ошибку:

undefined local variable or method `country_code' for #<Address:0x007fbae5bfb290> 

я попытался изменить способ:

def country_name 
    self.country = ISO3166::Country[country_code] 
    country.translations[I18n.locale.to_s] || country.name 
    end 

Это дает ту же ошибку, что и формулировки, которые не используют «я». Я думаю, что эти попытки не работают, потому что атрибут в моей адресной таблице называется «страна».

Когда я изменить метод для:

def country_name 
    self.country = ISO3166::Country[country] 
    country.translations[I18n.locale.to_s] || country.name 
    end 

я получаю сообщение об ошибке со словом «переводы». Когда я удалю '.перевод »из метода, я получаю сообщение об ошибке со словом« имя ».

Я теряю свой мрамор, пытаясь понять это.

ДРУГАЯ ПОПЫТКА

Я попытался добавить страны камень в мой файл гем (выше country_select).

Ничего не меняется, когда я связываю этот драгоценный камень. Та же проблема.

ДРУГАЯ ПОПЫТКА

Попытка снова (как я первоначально был метод определен), но со странами драгоценный камень установлен (выше country_select драгоценный камень):

def country_name 
    self.country = ISO3166::Country[country] 
    country.translations[I18n.locale.to_s] || country.name 
    end 

Я получаю эту ошибку: неопределенный метод `переводов для «Каймановых островов»: String

Это та самая проблема, с которой я изначально начинался, поэтому я не думаю, что добавление драгоценных камней в странах помогло продвинуться к решению.

+0

Является 'ISO3166 :: Country' из https://github.com/hexorx/countries? –

+0

No - country select gem: https://github.com/stefanpenner/country_select – Mel

+0

Правильно, но 'country_select' зависит от' стран'. –

ответ

3

Этот код хорошо работает для меня. У меня была страна столбец в моей таблице пользователя. На моей модели: -

def country_name 
    country = self.country 
    ISO3166::Country[country] 
    end 

в виде: -

<%= form_for @user do |f| %> 
     <%= country_select("user", "country") %> 
    <% end %> 
+0

Привет Purry, меняя мой метод country_name, чтобы он был таким же, как ваш. Я не понимаю, почему, но мне тоже все равно. Это заняло много времени. Большое спасибо – Mel

+0

Попробуйте выполнить регистрацию всех кодов предыдущего метода и этого. Там вы сможете увидеть ошибку. Если бы я мог помнить, country_code возвращает символ или пустое значение. И ты желанный :) – Purry

0

Вы не достаточно, есть некоторые моменты, которые должны сделать ошибку.

Во-первых,

def country_name 
    self.country = ISO3166::Country[country] 
    country.translations[I18n.locale.to_s] || country.name 
end 

В этом методы, вы должны четко country/self.country переменную или экземпляр. Я не могу себе представить, country это ISO3166::Country экземпляр или String

Во-вторых,
Разберитесь его использовать код ISO или название страны в качестве хэш ключа

Update:

у вас есть столбец страна, которая является строкой. вызов self.country = ISO3166::Country[country] означает присвоение ISO3166 :: Country экземпляра в переменной country(string). поэтому он делает ошибку.

Я не знаю, чего вы ожидаете.
Но вы должны использовать ключ ISO03166 :: Country как код ISO. подобный ISO3166::Country['AU']. И вы не можете назначить это в self.country.

def country_name 
    iso_county = ISO3166::Country[country] # `country` should be iso_code 
    iso_country.translations[I18n.locale.to_s] || iso_country.name 
end 

Если у вас есть название страны, а не код ISO в столбце страны. использовать ISO3166::Country.find_by_name

def country_name 
    iso_county = ISO3166::Country.find_by_name(country) # `country` should be name like 'Australia' 
    iso_country.translations[I18n.locale.to_s] || iso_country.name 
end 
+0

не уверен, что я понял. пожалуйста, не могли бы вы объяснить это больше? – Mel

+0

, пожалуйста, обновите свой вопрос, пожалуйста, опишите свою модель (wjth schema), которая имеет метод 'country_name' –

+0

Привет, я добавил таблицу адресов из схемы. Метод i, указанный выше, находится в моей адресу. Rb model – Mel

0

Похоже, ответ будет определенная комбинация предыдущих попыток.

Country_select использует коды стран вместо полных названий стран:

country_select("user", "country", priority_countries: ["GB", "FR", "DE"]) 

Это показано на странице GitHub для этого драгоценного камня: https://github.com/stefanpenner/country_select

С отборных возвращает код страны, то мы можем предположить, что атрибут страны будет кодом страны, а не полным именем страны. Имея это в виду, мы изменим предыдущий ответ:

def country_name 
    iso_country = ISO3166::Country[country] # `country` should be code like 'AU' 
    iso_country.translations[I18n.locale.to_s] || iso_country.name 
end 

Это передовая практика, чтобы избежать создания переменной с тем же именем, что и атрибут в этой модели, так придерживайтесь iso_country вместо страны в тестировании.

Проблема, с которой вы столкнулись, заключается в том, что при назначении объекту ISO3166 :: Country атрибуту объекта (self.country = ISO3166 :: Country [страна]) он не присваивает самому объекту ISO3166 :: Country к этому атрибуту, но вместо этого присваивает ему имя объекта ISO3166 :: Country.

Я проверил это в консоли Rails:

user = User.new 
    #<User:0x007ff7de29d1b8 
    id: nil, 
    ... 
user.country = ISO3166::Country['AU'] 
    #<ISO3166::Country:0x007ff7de3c6a08 
    @data= 
    {"continent"=>"Australia", 
    ... 
user.country 
    "Australia" 

Как вы можете видеть, присвоил название страны (а не объект страны) к атрибуту. Поэтому, когда вы пытаетесь получить доступ к country.translations или country.name, это вызовет ошибку, поскольку она обращается к атрибуту address, а не к объекту country. Поэтому определите имя переменной, отличное от имени атрибута.

Последнее, если у вас есть название страны, используйте метод find_country_by_name вместо find_by_name, так как find_by_name вернет массив, а find_country_by_name вернет объект Country. Это не должно быть необходимым в вашем текущем сценарии, но имейте это в виду, если вам нужно использовать его позже.