Как использовать области в контроллере и представлениях: Фильтруйте таблицу по категориям (enum), используя области в Rails - PullRequest
0 голосов
/ 25 мая 2019

У меня есть html-таблица в приложении rails, где я оплачиваю все свои расходы.Расходы - это перечисление, которое может принимать такие значения, как «образование», «пиво», «блиблаблуб».

Я хотел бы иметь возможность фильтровать мою HTML-таблицу в соответствии с этими значениями перечисления.У меня есть ссылки на той стороне таблицы, на которую пользователь может нажать.Теперь я хочу, чтобы таблица фильтровала результаты по ссылкам.

Теперь, я думаю, что суть здесь - путь, но мне трудно понять, как они на самом деле работают.Я создал такую ​​область видимости, чтобы понять это:

scope :find_category, -> {Expense.where(category:"education")}

В консоли Rails это работает, и когда я вызываю метод find_category, он дает мне примеры с образованием.

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

scope :find_category, -> (category) {Expense.where(category:category)}

Пока все хорошо.Теперь я не могу понять, как теперь использовать отфильтрованный результат в моем контроллере и просматривать его, то есть, как отфильтровать его при нажатии на ссылку.

Я попробовал это:

контроллер (пытается получить мои запрошенные результаты)

  def find_category
    @expense = Expense.find_category
    render action: :index
  end

А затем указать маршрут для find_categories:

  resources :expenses, path: 'expenses' do
    collection do
      get :find_category
    end
  end

и поместите ссылку в индексе:

 <%= link_to 'education', {controller: 'expenses', action: 'index', :find_category => 'education'}  %>

Я знаю, что это не совсем так.Нажав на ссылку, она дает мне expenses?find_category=education.Пока ничего не меняется.Поэтому я изо всех сил пытаюсь найти правильный способ сделать это.Конечно, было бы здорово сделать это без перезагрузки страницы, поэтому я думаю, что мне нужно использовать вызов AJAX и JavaScript.Но и с перезагрузкой страницы мне очень поможет.

1 Ответ

0 голосов
/ 25 мая 2019

При использовании enum Rails создает методы для вас, чтобы вы могли напрямую вызывать категорию, например Expense.education.

Вот пример того, как им управлять, довольно сырой , если вы используете стандартные соглашения Rails. Никакой специальной маршрутизации не требуется.


Определите константу, содержащую категории, например, в беспокойствах :
# model/concerns/expenses_stuff.rb
module ExpensesStuff
  extend ActiveSupport::Concern

  CATEGORIES = {category_a: 0, category_b: 100, category_c: 200 }

  module ClassMethods
   # class methods here
  end

  # instance methods here

end


В моделях включите модуль в класс расходов и определите поле категории как enum, выбирая константу:
# models/expense.rb
class Expense < ApplicationRecord
  include ExpensesStuff
  enum category: MaterialStuff::CATEGORIES
  # usual stuff
end


Теперь в контроллер . Будьте внимательны, чтобы принять значение фильтра, только если оно включено в MaterialStuff::CATEGORIES.keys.
# expenses_controller.rb
class ExpensesController < ApplicationController
# usual stuff
  def index
    @expenses = filtered_expenses
  end

 private
  def sanitized_category_filter
    category = params[:category].to_sym if params[:category]
    return category.to_sym if MaterialStuff::CATEGORIES.keys.include? category
    :all
  end

  def filtered_espenses
    Expense.public_send(sanitized_category_filter) # call directly the method
  end

end


Наконец, в view вы можете добавить свои фильтрующие ссылки.
# views/expenses/index.html.erb

<style>.bg-yellow {background-color:yellow;}</style> <!-- Move to *.css -->
<% def active_filter(category); 'bg-yellow' if category.to_s == params[:category]; end # move to helpers %>

<% (ExpensesStuff::CATEGORIES.keys << :all).each do |category| %>
  <%= link_to category, expenses_path(category: category), class: active_filter(category) %> |
<% end %>

Теперь вы можете добавлять новые категории, просто обновляя CATEGORIES Hash. Вы также можете использовать его в форме для выбора.

...