Rails 3 Active Record порядок отношений: используйте хеш вместо строки - PullRequest
4 голосов
/ 15 ноября 2011

Чтобы отсортировать отношение в Rails 3, мы должны сделать это:

User.where(:activated => true).order('id ASC')

Но я думаю, что это так:

User.where(:activated => true).order(:id => :asc)

будет иметь смысл, поскольку путь к имениэкранирование должно зависеть от адаптера (SqlLite vs Mysql vs PostgreSQL), верно?

Есть ли что-то похожее на это?

Ответы [ 3 ]

2 голосов
/ 26 ноября 2011

Я думаю, что ключевая проблема: ActiveRecord API не знает о порядке семантики . Он просто принимает строку и обходит базовую базу данных. К счастью, Sqlite, MySQL и PostgreSQL не имеют различий в синтаксисе order.

Я не думаю, что ActiveRecord может сделать эту абстракцию хорошо, и ей не нужно это делать. Он хорошо работает с реляционными базами данных, но его трудно интегрировать с NoSQL, например. MongoDB.

DataMapper , другой известный Ruby ORM, улучшил абстракцию. Взгляните на его синтаксис запроса :

@zoos_by_tiger_count = Zoo.all(:order => [ :tiger_count.desc ])

API осведомлен о семантике упорядочения. По умолчанию DataMapper сгенерирует оператор заказа SQL:

https://github.com/datamapper/dm-do-adapter/blob/master/lib/dm-do-adapter/adapter.rb#L626-634

def order_statement(order, qualify)
  statements = order.map do |direction|
    statement = property_to_column_name(direction.target, qualify)
    statement << ' DESC' if direction.operator == :desc
    statement
  end

  statements.join(', ')
end

Однако возможно переопределить на уровне адаптера БД:

https://github.com/solnic/dm-mongo-adapter/blob/master/lib/dm-mongo-adapter/query.rb#L260-264

def sort_statement(conditions)
  conditions.inject([]) do |sort_arr, condition|
    sort_arr << [condition.target.field, condition.operator == :asc ? 'ascending' : 'descending']
  end
end

TL; DR:

  • Вам не нужно беспокоиться о синтаксической проблеме, если вы используете только SqlLite, Mysql и PostgreSQL.
  • Для лучшей абстракции вы можете попробовать DataMapper.
2 голосов
/ 25 ноября 2011

Насколько я знаю, у этого синтаксиса, встроенного в ActiveRecord, нет опций, но добавить его не составит труда.Я нашел метод order, определенный в lib/active_record/relation/query_methods.rb.Теоретически, вы должны быть в состоянии сделать что-то вроде этого:

module ActiveRecord
  module QueryMethods
    def order(*args)
      args.map! do |arg|
        if arg.is_a? Hash
          # Format a string out of the hash that matches the original AR style
          stringed_arg
        else
          arg
        end
      end

      super
    end
  end
end
0 голосов
/ 26 ноября 2011

В этом конкретном случае вы можете сбросить бит «ASC», поскольку порядок во всей базе данных неявно возрастает

Foo.order(:bar)

Я знаю, что это не относится к случаю, когда вы хотите сделать order by bar desc, но на самом деле для порядка это не имеет большого значения, если вы не используете функции для предложения order by, и в этом случае может быть что-то как squeel поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...