3

我有一个像这样的当前城市和国家模型

# City model
city:string
country_code:string

# Country model
country:string
country_code:string

我正在尝试使用 country_code 作为 foreign_key 而不是使用默认的 country_id 在两个模型之间创建关联。

# city.rb
belongs_to :country, :foreign_key => "country_code"

# country.rb
set_primary_key :country_code
has_many :cities, :foreign_key => "country_code"

此查询不起作用

ruby-1.9.2-p290 :016 > Country.where(:country_code => "uy").cities
NoMethodError:   Country Load (0.2ms)  SELECT "countries".* FROM "countries" WHERE     "countries"."country_code" = 'uy'
undefined method `cities' for #<ActiveRecord::Relation:0x007f8e92ca0df0>
from /Users/pel/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-    3.2.3/lib/active_record/relation/delegation.rb:45:in `method_missing'
from (irb):16
    from /Users/pel/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start'
from /Users/pel/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start'
from /Users/pel/.rvm/gems/ruby-1.9.2-p290/gems/railties-    3.2.3/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
4

1 回答 1

3

试试这个:

Country.where(:country_code => "uy").collect(&:cities)

你缺少什么:

检查此错误:

 undefined method `cities' for #<ActiveRecord::Relation:0x007f8e92ca0df0>

其中条件返回一个对象数组。例如(考虑到存在 1 个 id,在某些情况下)

 Country.first // will return an object or nil

 Country.find(1) // will return an object or will throw an exception

 Country.where(:id=> 1) // will return an array of only one object with id 1

所以

  Country.find(1) IS NOT EQUAL TO Country.where(:id=> 1)

 Country.find(1) IS EQUAL TO Country.where(:id=> 1).first

以上就是基础知识。所以问题是

Country.where(:country_code => "uy") 

将返回一个数组,然后您尝试将“城市”映射应用于实际上不存在的该数组。因此,您需要做的是“收集”,它将遍历该数组中的所有对象,然后找出每个“国家”对象的城市并返回另一个数组数组

还有一点需要注意:

 Country.where(:country_code => "uy") 

将返回一个类似这样的数组:

['a','b','c','d']

Country.where(:country_code => "uy").collect(&:cities)

将返回一个数组,如:

  [[1,2,3,4],[2,3,6,8],[8],[10]] ie an array of an array.

所以你需要像这样展平它:

  Country.where(:country_code => "uy").collect(&:cities).flatten

然后,如果您需要唯一的城市(如果需要,根据记录,我认为您不需要这种情况),您可以将 .uniq 添加到数组中。

于 2012-04-23T20:33:47.233 回答