如何通过关系查询has_one?

时间:2015-06-16 14:49:04

标签: ruby-on-rails activerecord rails-activerecord

我的模特:
metro_station.rb

class MetroStation < ActiveRecord::Base
  belongs_to :metro_line
  has_one :city, through: :metro_line, autosave: false
end

metro_line.rb`

class MetroLine < ActiveRecord::Base
  belongs_to :city
  has_many :metro_stations
end

city.rb

class City < ActiveRecord::Base
  has_many :metro_lines
end

当我跑步时:
MetroStation.where(city: City.first)
我得到了

PG::UndefinedColumn: ERROR:  column metro_stations.city_id does not exist
: SELECT "metro_stations".* FROM "metro_stations" WHERE "metro_stations"."city_id" = 1
(pry) output error: #<ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column metro_stations.city_id does not exist
LINE 1: ...CT "metro_stations".* FROM "metro_stations" WHERE "metro_sta...

此查询有效:
MetroStation.joins(:metro_line).where(metro_lines: {city_id: 1})

2 个答案:

答案 0 :(得分:2)

找出你的第一种方法为什么不能输入

MetroStation.where(city: City.first).to_sql

您应该看到类似

的内容
... WHERE metro_stations.city_id = 1

构成查询的一部分。 MetroStation模型根本没有city_id属性,因此您的第一种方法形成了无效的SQL语句。

加入有效,因为它在MetroLine表上进行过滤,该表与city_id字段形式的城市模型有关系。

你的模型没有任何问题,只是Rails生成SQL语句的方式,这在SQL世界中是有意义的。

通过MetroLine在City到MetroStation上的has_many关系可以为您的问题提供所需的结果(哪个地铁站位于城市中)。

实施例

class City < ActiveRecord::Base
  has_many :metro_lines
  has_many :metro_stations, through: :metro_lines
end

class MetroLine < ActiveRecord::Base
  belongs_to :city
  has_many :metro_stations
end

class MetroStation < ActiveRecord::Base
  belongs_to :metro_line
  has_one :city, through: :metro_line
end


# Return all metro stations for a city
# * assuming City has name 'name' field
london_stations = City.find_by_name('London').metro_stations 

希望这有帮助!

答案 1 :(得分:1)

城市也应该:

has_many :metro_stations, :through => :metro_lines

然后你写道:

City.first.metro_stations