Используя гем Active Record Reputation System, сортировка не происходит, когда я сортирую по голосам

Следуя RailsCast для системы репутации, я добавил следующий код в свой microposts_controller.

def index
  @microposts = Micropost.paginate(page: params[:page]).find_with_reputation(:votes, :all, order: "votes desc")
  @micropost  = current_user.microposts.build
end

Но в моем действии index не происходит сортировки, кроме области действия по умолчанию, которую я установил в своей модели.

В моей модели микросообщения у меня есть

class Micropost < ActiveRecord::Base
    belongs_to :user
    has_many :retweets
    has_reputation :votes, source: :user, aggregated_by: :sum
    default_scope -> { order('created_at DESC') }

Если я изменю область действия по умолчанию на

default_scope -> { order('votes DESC') }

Он работает так, как я хочу, только для индексной страницы, но ломает все остальные мои страницы.

Я попытался удалить область по умолчанию и оставить метод find_with_reputation, но он по-прежнему не упорядочивает голоса.

Я также попытался определить область действия в методе модели микросообщения, подобной этой.

  def self.popular
    find_with_reputation(:votes, :all, {:order => 'votes desc'})
  end

И сделайте код в microposts_controller таким

  def index
    @microposts = Micropost.paginate(page: params[:page]).popular
    @micropost  = current_user.microposts.build
  end

Он по-прежнему не сортирует по голосам.

Вот копия вывода журнала посещения индексной страницы микросообщений https://gist.github.com/anonymous/9745552

Вот ссылка на гем https://github.com/NARKOZ/activerecord-reputation-system/tree/rails4

Мой route.rb для микропостов выглядит так

  resources :microposts, only: [:create, :destroy, :index] do
    member { post :vote }
    member { post :retweet}
  end

Любое руководство приветствуется.

Обновить

Лента моей домашней страницы разработана иначе, чем фид индекса Micropost. Возможно, сравнение того, что работает, с тем, что не работает, поможет выявить проблему.

У меня есть контроллер статических страниц, который устанавливает область действия для домашнего действия, подобного этому.

def home
      @micropost  = current_user.microposts.build
      @feed_items = current_user.feed.paginate(page: params[:page])
end

В пользовательской модели я определяю метод подачи, используемый в контроллере статических страниц, например так

def feed
  Micropost.from_users_followed_by_including_replies(self)
end

метод from_users_followed_by_including_replies(self) — это область действия, которую я установил в модели микросообщения.

scope :from_users_followed_by_including_replies, lambda { |user| followed_by_including_replies(user) }

 def self.followed_by_including_replies(user)
      followed_ids = %(SELECT followed_id FROM relationships
                       WHERE follower_id = :user_id)
      where("user_id IN (#{followed_ids}) OR user_id = :user_id OR to_id = :user_id",
            { :user_id => user })
 end

Возможно, мне нужно адаптировать аналогичный подход к действию Index для контроллера Microposts.


person heartmo    schedule 24.03.2014    source источник
comment
это работает без области по умолчанию?   -  person NARKOZ    schedule 25.03.2014
comment
К сожалению нет. Когда я удаляю область по умолчанию, она все равно не сортируется правильно. Вот копия моего журнала без области по умолчанию gist.github.com/anonymous/9766989   -  person heartmo    schedule 25.03.2014


Ответы (1)


ИЗМЕНИТЬ

Получив код, я обнаружил, что настоящая проблема связана с использованием default_scope.

Исходное предложение order(), указанное в вашей области действия по умолчанию, по-прежнему применяется, даже при добавлении вашего собственного order().

Кстати, эта проблема была отчасти исправлена ​​в Rails 4.0, но в версии 4.0.1 поведение было восстановлено.

Решение состояло в том, чтобы применить reorder()

# model
def self.popular
  reorder('votes desc').find_with_reputation(:votes, :all)
end

# controller
def index
  @microposts = Micropost.page(params[:page]).popular
end

ИСХОДНЫЙ ОТВЕТ

Похоже, что использование метода paginate непосредственно может не работать с activerecord-reputation-system,

Однако я нашел несколько примеров, показывающих, что вы можете использовать методы will_paginate page и per:

Возможно, это будет работать так:

Micropost.page(params[:page]).per(30).find_with_reputation(:votes, :all, order: "votes desc")

Или с такой областью действия модели:

def self.popular
  find_with_reputation(:votes, :all, order: 'votes desc')
end

вы можете сделать это:

Micropost.page(params[:page]).per(30).popular

Кроме того, в качестве примечания, ваш файл маршрутов немного странный с несколькими блоками member, когда необходим только один. Я бы сделал так:

resources :microposts, only: [:create, :destroy, :index] do
  member do
    post :vote
    post :retweet
  end
end
person Unixmonkey    schedule 25.03.2014
comment
Спасибо, что указали на исправление в моем файле маршрутов. Я попытался настроить область действия так, как она у вас есть, а также отредактировать вызов разбиения на страницы, и все равно не повезло. Я также полностью удалил нумерацию страниц, и она по-прежнему сортируется только по области действия по умолчанию. - person heartmo; 25.03.2014
comment
Это была именно проблема! - person heartmo; 26.03.2014