Как заказать включенные элементы в Rails 3 - PullRequest
40 голосов
/ 18 марта 2011

У меня есть модельное отношение, в котором today имеет много tasks

Я пытаюсь получить пользовательский объект today, включить tasks и отобразить их все в Json.Все это шло отлично, пока я не решил заказать tasks внутри объекта today, потому что respond_with block также используется для рендеринга html-страницы.Есть ли способ включить tasks и упорядочить их?

Я пытаюсь что-то вроде этого:

class TodaysController < ApplicationController
  respond_to :html, :json
  def show
    @today = Today.where(:user_id => current_user.id).joins(:tasks).includes(:tasks).order(:priority).first
    respond_with @today, :include => :tasks
  end
end

Это возвращает все правильно, но, кажется, не упорядочить задачина всех.

Это то, что у меня было (что работало отлично, но не было порядка):

class TodaysController < ApplicationController
  respond_to :html, :json
  def show
    @today = current_user.today
    respond_with @today, :include => :tasks
  end
end

Я знаю, что могу получить данные и отсортировать их потомвот так:

@today = current_user.today
@today.tasks.sort!{|a,b| a.priority <=> b.priority }

Это работает и пройдет мои тесты, но я надеялся, что ActiveRecord сможет решить эту проблему.

Ответы [ 2 ]

59 голосов
/ 18 марта 2011

Попробуйте это в вашей Today модели:

has_many :tasks, :order => 'priority DESC'

РЕДАКТИРОВАТЬ: Как уже упоминалось в комментарии ниже, в Rails 4+ это сейчас:

has_many :tasks, -> { order(:priority => :desc) }

( подробнее здесь )

42 голосов
/ 28 мая 2013

Прямым решением было бы включить tasks имя таблицы перед priority:

Today.where(:user_id => current_user.id).includes(:tasks).order('tasks.priority').first
# joins(:tasks) is not required

Или, если вы не хотите, чтобы имя таблицы было жестко закодировано, вы можете объединить с областью действия изTask модель:

Today.where(:user_id => current_user.id).joins(:tasks).includes(:tasks).merge(Task.order(:priority)).first
# joins(:tasks) here is required

Кроме того, вы можете добавить has_many: todays к User модели, чтобы отказаться от предложения where и сделать:

current_user.todays.includes(:tasks).order('tasks.priority').first
# or
current_user.todays.joins(:tasks).includes(:tasks).merge(Task.order(:priority)).first

Но если вам нужнотолько / всегда для упорядочения по приоритету и не требуются другие различные упорядочения, добавление order к has_many :tasks проще.

...