Filtrowanie rekordów dla admina i usera - krytyka rozwiązania

Wszelkie uwagi a nawet wiadra pomyj mile widziane. Po kolei:
Mamy 2 klasy userów: normalny i admin.
Mamy model Bet, który dzieli się na 6+1 zdefiniowanych na podstawie różnych parametrów kategorii (statusów):

class Bet < ActiveRecord::Base
    scope :visible, lambda { where('bets.published_at IS NOT NULL and bets.banned = ?', 0) }
    scope :active, lambda { visible.where('bets.deadline > ? and bets.closed_at IS NULL', Time.now.strftime("%Y-%m-%d")) }
    scope :waiting, lambda { visible.where('bets.deadline <= ? and bets.closed_at IS NULL', Time.now.strftime("%Y-%m-%d")) }
    scope :closed, lambda { visible.where('bets.closed_at IS NOT NULL') }
    scope :created, lambda { where('bets.published_at IS NULL and bets.closed_at IS NULL') }
    scope :rejected, lambda { where('bets.published_at IS NULL and bets.closed_at IS NOT NULL') }
    scope :banned, lambda { where('bets.banned = ?', 1) }

6+1 jest dlatego, że “visible” jest pomocniczo, żeby uprościć definicję 3 innych kategorii.
Definicje etykiet do wyświetlania wyglądają tak (nazwa scope’a => tekst etykiety/linka):

private

def Bet.status_names(admin)
	statuses = { 
		'active' => 'aktywne', 
		'waiting'  => 'oczekujące', 
		'closed' => 'zakończone',
	} 
	if admin == true
		return statuses.merge({
			'created' => 'nowe',
			'rejected' => 'odrzucone', 
			'banned' => 'usunięte' 
		})
	end
	statuses
end

def Bet.order_names
	{ 'oldest' => 'najstarsze', 'newest' => 'najnowsze' }
end

(‘oldest’ i ‘newest’ to wiadomo - dodane sortowanie).
Kontroler pobiera te hashe żeby przekazać do widoku i wyświetlić oraz pobiera rekordy na podstawie parametrów.

def index
  @bets = Bet.for_display(params)
  @status_names = Bet.status_names(current_user.admin?)
  @order_names = Bet.order_names
  @categories = Category.all
  @status = @status_names.keys.include?(params[:status]) ? @status_names[params[:status]] : 'widoczne'
end

Widok:

<div>Pokaż: <%= render partial: 'shared/querystring', locals: { key: 'status', object: @status_names } %></div>

i partial (wiem, lepsza nazwa by się przydała ;)):

<% object.each do |name, value| %>
  <%= link_to value, "/bets/?#{query_string(params, key, name)}" %>
<% end %>

query_string() formatuje parametry, żeby zastąpić tylko odpowiedni z nich nową wartością.

I jest wszystko fajnie tylko że w metodzie wyszukującej rekordy również korzystam z Bet.status_names, żeby nie wywołać nieprawidłowego scope (btw. jaka nazwa obowiązuje po polsku na to?).

def Bet.for_display(params)
  scope1 = status_names(true).keys.include?(params[:status]) ? Bet.send(params[:status]) : Bet.visible
  if scope1 && !params[:order].nil?
    scope2 = Bet.send(params[:order])
  end
  merged = scope1 ? scope1.merge(scope2) : nil
  if merged && !params[:category].nil?
    scope3 = Bet.where('category_id = ?', params[:category])
  end
  merged = merged ? merged.merge(scope3) : []
end

Oczywiście w takiej postaci będą wyświetlane 3 etykietki dla usera a 6 dla admina ale i tak można zobaczyć inne przez wpisanie np. ?status=banned w adresie.
Można to zabezpieczyć przez dołączenie parametru ‘admin’ dodatkowo:
def Bet.for_display(params, admin)
i w pierwszej linii status_names(admin) zamiast true.
No ale… nie pasuje mi coś w tym rozwiązaniu, dlatego chciałbym usłyszeć jakieś opinie, co tu jest źle i jak to można rozwiązać bardziej elegancko.
Myślałem np. żeby zamiast tych wszystkich warunków dać jedno pole pt “status” co by uprościło filtrowanie.

Abstrahując już od samego problemu filtrowania wyników - do tego typu problemów polecam: https://github.com/pluginaweek/state_machine

Proponuję zrobić osobną klasę, która będzie odpowiadała za wyciąganie i filtrowanie rekordów bazy np. QueryBets, która będzie przyjmowała parametry zapytania oraz użytkownika, która jest aktualnie zalogowany. I w niej zrób sobie metody, którą będą zwracały rekordy, możliwe statusy, możliwe rodzaje sortowania. Coś w tym stylu

class QueryBets
  def initialize(params, user)
  end
  def results
    # zwraca przefiltrowane rekordy
  end
  def status_names
    # zwraca dostępne statusy
  end
  def order_names
    # zwraca dostępne rodzaje sortowania
  end
end

Wtedy w kontrolerze wystarczy zrobić coś takiego:

def index
   @query = QueryBets.new(params, current_user)
end

A w widokach odwołujesz się do poszczególnych danych przez @query.results albo @query.status_names itd.