【问题标题】:Rails 4 - Country Select & Simple FormRails 4 - 国家选择和简单表格
【发布时间】:2016-01-01 22:23:34
【问题描述】:

我正在尝试在 Rails 4 中制作应用程序。我对表单使用简单的表单,对国家/地区列表使用 country_select gem。

我有一个地址模型,其中包括这个方法:

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 %>   

然后记录显示 - 但显示为 AU 而不是澳大利亚(这是地址模型中的方法提供的)。

地址表:

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

接受在铉的建议,

我将地址模型中的国家名称方法更改为:

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

这给出了与不使用“self”的公式相同的错误。我认为这些尝试不起作用,因为我的地址表中的属性称为“国家”。

当我将方法更改为:

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

我收到“翻译”一词的错误。当我从方法中删除 '.translations' 时,我收到一个包含单词 'name' 的错误。

我正在失去理智试图弄清楚这一点。

另一个尝试

我尝试将国家 gem 添加到我的 gem 文件中(在 country_select 上方)。

当我捆绑这个 gem 时没有任何变化。同样的问题。

另一个尝试

再试一次(因为我最初定义了方法),但安装了国家 gem(在 country_select gem 之上):

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

我收到此错误:“开曼群岛”的未定义方法“翻译”:字符串

这与我最初开始时遇到的问题相同,因此我认为添加国家/地区 gem 并没有帮助解决问题。

【问题讨论】:

标签: ruby-on-rails simple-form country-codes


【解决方案1】:

这段代码很适合我。我的用户表中有 country 列。 在我的模型上:-

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

形式:-

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

【讨论】:

  • 嗨 Purry,将我的 country_name 方法更改为与您的相同。我不明白为什么,但我也不在乎。这需要很长时间才能解决。非常感谢
  • 尝试记录上一个方法的每个代码和这个。您将能够在那里看到错误。如果我记得的话, country_code 返回一个符号或一个空值。不客气:)
【解决方案2】:

你的问题还不够,有些地方应该出错。

首先,

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

在这个方法中,你应该明确country / self.country变量或实例。我无法想象countryISO3166::Country 实例还是String

第二,
明确它使用 ISO 代码或国家名称作为哈希键

更新:

您的国家列是字符串。 调用self.country = ISO3166::Country[country] 意味着在country(string) 变量中分配ISO3166::Country 实例。所以会出错。

我不知道你期待什么。
但是您应该使用 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

【讨论】:

  • 不确定我是否理解。请你再解释一下吗?
  • 请更新您的问题,请描述您的具有country_name 方法的模型(wjth 架构)
  • 嗨,我从架构中添加了地址表。我上面列出的方法在我的address.rb模型中
  • @JaehyunShin ,应该把ISO3166::Country.find_by_name[country] 改成ISO3166::Country.find_by_name(country) 吗?
  • 嗨 - 它给出了这个错误:未定义的方法 `translations' for nil:NilClass
【解决方案3】:

看起来答案将是您之前尝试的某种组合。

Country_select 使用国家代码而不是完整的国家名称:

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

这显示在该 gem 的 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[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 时,它​​将引发错误,因为它正在访问地址属性而不是国家/地区对象。所以一定要保持变量名与属性名不同。

最后一件事,如果您确实有国家名称,则使用方法 find_country_by_name 而不是 find_by_name,因为 find_by_name 将返回一个数组,而 find_country_by_name 将返回一个 Country 对象。在您当前的情况下,这应该不是必需的,但如果您以后需要使用它,请记住它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多