In the first part of this tutorial, we used the ez_where plugin to build a more complex search filter into a User model class. In this tutorial, we’ll extend the search filters with additional criteria, and in part 3 we’ll build a controller that ties all the functionality together.

Searching Email Addresses for Terms

Currently, our User class’ search method accepts a :terms key as part of its options hash that is used to filter first and last names. For searches, I prefer a single text box that searches all the text data in a model - Google style - rather than separate boxes for first name, last name, email address, etc. To make the :terms filter search email addresses, just add the highlighted line to your code:

You could now search for all users named Mary with an email address at company.com using:

rubyUser.search :all, :filters => { :terms => %w(mary company.com)}

Filtering Additional Criteria

For large data sets, you’ll probably need to add more granular filters, search as searching for active or inactive clients, or searching for users who are only admins. Our User.search method can be extended to do that by adding more options to the :filters hash:

```ruby# app/models/user.rb

Apply the :admin filter

unless filters[:admin].nil?

condition = Caboose::EZ::Condition.new :users do

admin == filters[:admin]

end

combined_conditions « condition

end```

Notice here I’ve used ez_where’s block notation to build the condition. Within the do...end, you can make use of ez_where’s ruby-like syntax for conditions. For example,

There are other operators as well (see the documentation), and you can even nest conditions within a block for complex queries. However, each of these conditions is joined with an AND clause, which is why we couldn’t use the block notation for the :terms filter.

Finally, we’ll add the :status option to our User.search:filters hash. In our User model, status is an integer representing the user’s state or level of authorisation. This could be represented in a settings hash, for example:

```ruby:normal => 0,

:author => 1,

:editor => 2```

Our :status filter will take an array of states and use the SQL IN clause to filter the appropriate users:

```ruby# app/models/user.rb

Apply the :status filter

unless filters[:status].nil?

condition = Caboose::EZ::Condition.new :users do

status === [*filters[:status]] # use [*obj] rather than obj.to_a as Object.to_a is depracated

end

combined_conditions « condition

end```

So, we can now filter users by their status and/or admin attributes using:

The next post will show how to build a controller and search form that lets users filter perform complex searches using the new User.search method that we’ve built. In the meantime, please discuss in the comments.