7

我正在开发一个使用 Datamapper 作为其 ORM 的 Rails 3.2 应用程序。我正在寻找一种通过关联模型的属性对结果集进行排序的方法。具体来说,我有以下模型:

class Vehicle
  include DataMapper::Resource

  belongs_to :user
end

class User
  include DataMapper::Resource

  has n, :vehicles
end

现在我希望能够查询车辆并按驾驶员姓名对其进行排序。我尝试了以下方法,但似乎都不适用于 Datamapper:

> Vehicle.all( :order => 'users.name' )
ArgumentError: +options[:order]+ entry "users.name" does not map to a property in Vehicle

> Vehicle.all( :order => { :users => 'name' } )
ArgumentError: +options[:order]+ entry [:users, "name"] of an unsupported object Array

现在我正在使用 Ruby 对查询后的结果集进行排序,但显然这对性能没有任何帮助,它也阻止了我进一步链接其他范围。

4

3 回答 3

7

我花了更多时间四处挖掘,终于找到了一个旧博客,它可以解决这个问题。它涉及在 DataMapper 中手动构建排序查询。

来自:http ://rhnh.net/2010/12/01/ordering-by-a-field-in-a-join-model-with-datamapper

def self.ordered_by_vehicle_name direction = :asc
  order = DataMapper::Query::Direction.new(vehicle.name, direction)
  query = all.query
  query.instance_variable_set("@order", [order])
  query.instance_variable_set("@links", [relationships['vehicle'].inverse])
  all(query)
end

这将让您通过关联进行排序并仍然链接其他范围,例如:

User.ordered_by_vehicle_name(:desc).all( :name => 'foo' )

这有点hacky,但它至少做了我想做的事情;)

于 2012-09-27T14:09:31.370 回答
1

注意:我不熟悉 DataMapper,我的回答可能不在使用 DataMapper 的标准和建议范围内,但它应该有望为您提供您正在寻找的结果。


我一直在浏览各种 Google 搜索和 DataMapper 文档,但还没有找到“按关联属性排序”的方法。我想到的唯一解决方案是“原始”SQL。

查询看起来像这样。

SELECT vehicles.* FROM vehicles
LEFT JOIN users ON vehicles.user_id = users.id
ORDER BY users.name

不幸的是,据我了解,当您直接查询数据库时,您不会获取Vehicle对象,而是从数据库中获取数据。

来自文档:http ://datamapper.org/docs/find.html 。它位于标题为“直接与您的数据存储区对话”的底部附近

请注意,这不会返回 Zoo 对象,而是直接来自数据库的原始数据

于 2012-09-23T14:53:29.427 回答
-3
Vehicle.joins(:user).order('users.name').all

或在 Rails 2.3 中,

Vehicle.all(:joins => "inner join users on vehicles.user_id = user.id", :order => 'users.name')
于 2012-09-14T17:50:16.597 回答