Создание формы фильтра в представлениях

#ruby-on-rails

#ruby-on-rails

Вопрос:

Итак, я пытаюсь отфильтровать данные, представленные в моем индексном действии, с помощью области видимости.

Я определил это так в profile.rb

 scope :fees_to, -> (fees_to) { where("fees_to <= ?", "#{fees_to}") }
  

Он отлично работает в консоли rails, я могу сделать Profile.fees_to(50) , например, и возвращает все профили, у которых fees_to меньше 50.

Что я хотел бы знать, так это как мне создать этот метод входного фильтра в моих индексных представлениях?

profiles_controller.rb Для действия с индексом код выглядит следующим образом:

 def index
  @profiles = Profile.where(nil)
  @profiles = @profiles.fees_to(params[:fees_to]) if params[:fees_to].present?
end
  

Я пытался собирать информацию в своем индексном представлении различными способами, все, чтобы знать, полезно.

Буду признателен за любую помощь или совет. Спасибо!

Комментарии:

1. Попробуйте @profiles = Profile.fees_to(params[:fees_to]) if params[:fees_to].present? вместо @profiles = @profiles.fees_to(params[:fees_to]) if params[:fees_to].present?

2. @Pavan не могли бы вы любезно объяснить разницу между использованием Profile. вместо @profile ? Кроме того, я не очень понимаю, как я должен отображать свою форму для сбора. В настоящее время я пытаюсь <% form_for @profiles do |f| %> , но он выдает ошибку.

3. Области видимости — это методы класса. Они должны вызываться в классе, подобном ClassName.ScopeName .

4. Вполне допустимо создавать области видимости в несколько шагов @Pavan.

5. @max означает ли это, что код в моем контроллере в порядке? Как вы думаете, вы могли бы помочь мне с отображением представления для формы?

Ответ №1:

Обновление: этот ответ полностью устарел. Использовать form_with для обоих типов форм в Rails 5

Обычно при создании форм в rails вы используете form_for для создания формы, привязанной к одному экземпляру модели, например: form_for(@thing) .

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

 <%= form_tag(profiles_path, method: :get) do %>
  <% label_tag 'fees_to', 'Maximum fee' %>
  <% number_field_tag 'fees_to' %>
  <% submit_tag 'Search' %>
<% end %>
  

 def index
  @profiles = Profile.all
  @profiles = @profiles.fees_to(params[:fees_to]) if params[:fees_to].present?
end
  

объясните разницу между использованием Profile. вместо @profile?

Profile является константой, которая в данном случае содержит класс Profile . @profile является переменной экземпляра — в данном контексте она принадлежит контроллеру и, скорее всего, будет nil , поскольку это действие индекса.

 Profile.fees_to(50) # calls the class method `fees_to` on `Profile`.
@profile.fees_to(50) # will most likely give a `NoMethodError`.
  

Однако, когда вы делаете:

 @profiles = Profile.all
@profiles = @profiles.fees_to(params[:fees_to]) if params[:fees_to].present?
  

Происходит то, что вы просто объединяете вызовы области видимости, как в этом примере:

 @users = User.where(city: 'London')
             .where(forename: 'John')
  

за исключением того, что вместо цепочки вы изменяете переменную @profiles .

Комментарии:

1. привет, Макс, спасибо за предоставление решения. однако фильтр не работает. я вижу эту строку в журнале сервера Parameters: {"utf8"=>"✓", "Fees_to"=>"10"} , но, похоже, она не Profiles.all.fees_to(10) работает в моей консоли rails.

2. Попробуйте использовать number_field_tag 'fees_to' . По какой-то причине он изменил регистр при использовании символа.

3. только что понял, что допустил опечатку в разделе ‘fees_to’. работает отлично! большое вам спасибо!