2014-11-21 2 views
0

Мне интересно, какая удивительная функция может помочь в сортировке по атрибутам модели или виртуальным атрибутам модели.Сортировка рельсов по виртуальному атрибуту, сгенерированному методом модели

У меня есть модель под названием Box с некоторыми атрибутами. Я показываю в своем индексе список этих полей с атрибутами и статусом. Этот статус немного особенный, прежде чем он сгенерирован и не будет записываться в моей базе данных (мы говорим о статусе реального времени, нет никакого интереса к его записи).

Я столкнулся с проблемой сортировки этого статуса.

Моя идея заключается в следующем:

#Box.rb 
attr_accessor :status 

def generate_status 
    self.status = "awesome status" 
end 

def status 
    @status 
end 

def status=(val) 
    @status = val 
end 

И я хотел бы получить доступ к этой информации на моем контроллере

#BoxesController.rb 
@boxes = Box.all #With my sort by virtual attribute status 

Я не хочу делать (не зная, как сортировать виртуальный атрибут):

@boxes = Box.all 
@boxes.each do |b| 
    b.status = b.generate_status 
end 

Наконец, если это возможно, я обобщу это на все перечисленные мной думаю, на моей модели через Concern я думаю. Но, чтобы начать эту работу мне нужно знать, если это возможно, чтобы сортировать виртуальный атрибут

Edit:

Теперь я пытаюсь с этим способом в объеме:

#In a Concern included in my model 
(["status"] rescue []).each do |method| 
    scope "sort_by_#{method}", ->(order){ 
    if order.equal?("asc") 
     self.where(nil).sort!{|a,b| a.send(method) <=> b.send(method)} 
    else 
     self.where(nil).sort!{|a,b| b.send(method) <=> a.send(method)} 
    end 
    } 
end 

Там не является ошибкой, но мои элементы не отсортированы.

Обратите внимание, что я назвал ["status"] временным, потому что я в настоящее время пытается получить доступ к этой переменной, объявленной на моей модели (где мое беспокойство в комплекте)

Спасибо за вашу помощь!

ответ

0

Невозможно сортировать по виртуальному атрибуту с помощью ActiveRecord, однако мы можем использовать результат sort_by!. http://www.ruby-doc.org/core-2.1.5/Array.html#method-i-sort_by-21

@boxes.sort_by! { |a,b| a.status <=> b.status } 

Чтобы автоматически установить статус, вы можете использовать after_find обратного вызова.

#Box.rb 
attr_accessor :status 

after_find :generate_status 

def generate_status 
    self.status = 'awesome status` 
end 
+1

'sort_by' не работает. У меня есть эта ошибка 'NoMethodError: undefined method status 'для nil: NilClass'. Но 'Box.all.map {| b | b.status} 'работает. Кажется, что переменная 'b' в' sort_by' равна нулю. – BriceB

+0

Вы уверены, что массив содержит как минимум 2 элемента? – KPheasey

Смежные вопросы