angkiki
angkiki

Reputation: 495

Creating Filter Form in Views

So i am trying to filter the data that is presented in my Index action by using scope.

I have defined it as so in profile.rb

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

It works perfectly fine in rails console, i can do Profile.fees_to(50) for example and it returns all profiles that has fees_to that are less than 50.

What i would like to know is how do i create this input filter method in my index views?

In profiles_controller.rb for Index action, the code is as follows:

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

I've tried collecting the information in my index view in various ways, all to know avail.

Any help or advice would be greatly appreciated. Thanks!

Upvotes: 1

Views: 870

Answers (1)

max
max

Reputation: 102218

Update: This answer is completely obsolete. Use form_with for both kinds of forms in Rails 5+

Usually when creating forms in rails you use form_for to create a form is bound to a single model instance for example: form_for(@thing).

However when constructing something like a search query or filters you just want a plain old form without any data binding since the goal is not to create or modify a resource.

<%= 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

explain the difference between using Profile. instead of @profile?

Profile is a constant - which in this case contains the class Profile. @profile is a instance variable - in this context it belongs to the controller and will most likely be nil since it is the index action.

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

However when you are doing:

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

What is happening is that you are just chaining scope calls like in this example:

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

except that instead of chaining you are mutating the variable @profiles.

Upvotes: 1

Related Questions