rails:使用活动记录查询和过滤n:m相关对象

时间:2013-05-07 19:21:52

标签: ruby-on-rails activerecord

我正在尝试使用活动记录查询机场之间的可能连接。 我在这里描述了我在另一个问题中创建的模型:

n:m self-join with ruby on rails active record

基本上,我现在能做的是:

ny = Airport.create({"city" => "New York"})
la = Airport.create({"city" => "Los Angeles"})

ny.destinations << la
la.destinations << ny

我遇到了一个查询我正在寻找的数据的问题,这在SQL中非常简单,但我对活动记录没有运气。

ny = Airport.where('city = ?', 'New York')
ny.destinations

返回正确的对象,但都是。

SQL查询看起来像这样:

 SELECT "airports".* FROM "airports" INNER JOIN "connections" ON "airports"."id" = "connections"."destination_id" WHERE "connections"."airport_id" = 3

我想按照以“s”开头的城市过滤这些结果,因此SQL查询可能如下所示:

SELECT "airports".* FROM "airports" INNER JOIN "connections" ON "airports"."id" = "connections"."destination_id" WHERE "connections"."airport_id" = 3 AND airports"."city" LIKE "s%"

我试过这种方式:

ny.destinations.where('city LIKE ?', '#{params[:query]}%')

但我总是得到一个空洞的结果。

如何使用有效记录来过滤生成的对象?

编辑:这是我到目前为止找到的最佳解决方案:

我将cityLike()方法添加到机场模型中:

应用程序/模型/ airport.rb:

class Airport < ActiveRecord::Base
  attr_accessible :city, :name

  has_many :connections
  has_many :destinations, :through => :connections
  has_many :inverse_connections, :class_name => "Connection", :foreign_key => "destination_id"
  has_many :inverse_destinations, :through => :inverse_connections, :source => :airport

  def self.cityLike(query)
    where("city LIKE ?", "%#{query}%")
  end
end

应用程序/模型/ connection.rb:

class Connection < ActiveRecord::Base
  attr_accessible :destination_id, :airport_id

  belongs_to :airport
  belongs_to :destination, :class_name => "Airport"
end

现在我可以使用以下语句查询对象:

Airport.find(1).destinations.cityLike("a")

不确定它是否是最佳解决方案,但它会产生我正在寻找的查询。

非常感谢你们所有人!

3 个答案:

答案 0 :(得分:0)

ActiveRecord::Base.execute(sql)允许您使用纯SQL进行查询并返回相关模型。

答案 1 :(得分:0)

这个怎么样?

Airport.find(:all, joins: "INNER JOIN `connections` ON airports.id = connections.destination_id").where("connections.airport_id = ? AND airports.city LIKE ?", ny_id, "s%")

答案 2 :(得分:0)

此代码:

ny.destinations.where('city LIKE ?', '#{params[:query]}%')

就像这样 - 首先你有一个对象,它重复纽约市。当您说“.destinations”时,您现在已经遵循了您在模型中定义的关系,以检索您可以从纽约获得的所有目的地。但是,如果我正确地想象您的数据库模式,这些目标实际上并没有一个名为“city”的字段;相反,他们有一个destination_id,它将目的地与特定机场联系起来,而且它是一个与之相关的城市的机场。

因此,当您查询目标表中的“城市LIKE?”时,它找不到任何匹配的记录。

相反,请尝试

ny.destinations.joins(:airports).where('city LIKE ?', '#{params[:query]}%')