#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’. работает отлично! большое вам спасибо!