FortyFacets

FortyFacets lets you easily build explorative search interfaces based on fields of your active_record models.

  • Owner: FortySource/forty_facets
  • Platform:
  • License:: MIT License
  • Category::
  • Topic:
  • Like:
    0
      Compare:

Github stars Tracking Chart

Build Status
Coverage Status
Code Climate
forty_facets API Documentation

FortyFacets

FortyFacets lets you easily build explorative search interfaces based on fields of your ActiveRecord models.

demo

See it implemented in a example rails application or
try a working demo!

It offers a simple API to create an interactive UI to browse your data by iteratively adding
filter values.

The search is purely done via SQL queries, which are automatically generated via the AR-mappings.

Narrowing down the search result is done purely via GET requests. This way all steps are bookmarkable. This way the search natively works together with turbolinks as well.

There is no JavaScript involved. The collection returned is a normal ActiveRecord collection - this way it works seamlessly together with other GEMs like will_paginate

Installation

Add this line to your application's Gemfile:

gem 'forty_facets'

And then execute:

$ bundle

Or install it yourself as:

$ gem install forty_facets

Usage

You can clone a working example at https://github.com/fortytools/forty_facets_demo

If you have Movies with a textual title, categotized by genre, studio and year with studios belonging to a country...

class Movie < ActiveRecord::Base
  belongs_to :year
  belongs_to :studio
  has_and_belongs_to_many :genres

  scope :classics, -> { where("year <= ?", 1980) }
end

You can then declare the structure of your search like so:

class HomeController < ApplicationController

  class MovieSearch < FortyFacets::FacetSearch
    model 'Movie' # which model to search for
    text :title   # filter by a generic string entered by the user
    scope :classics   # only return movies which are in the scope 'classics'
    range :price, name: 'Price' # filter by ranges for decimal fields
    facet :year, name: 'Releaseyear', order: :year # additionally order values in the year field
    facet :studio, name: 'Studio', order: :name
    facet :genres, name: 'Genre' # generate a filter with all values of 'genre' occuring in the result
    facet [:studio, :country], name: 'Country' # generate a filter several belongs_to 'hops' away

    orders 'Title' => :title,
           'price, cheap first' => "price asc",
           'price, expensive first' => {price: :desc, title: :desc}
    custom :for_manual_handling

  end

  def index
    @search = MovieSearch.new(params) # this initializes your search object from the request params
    @movies = @search.result.paginate(page: params[:page], per_page: 5) # optionally paginate through your results
  end

In your view you can iterate the result like any other ActiveRecord collection

%table.table.table-condensed
  %tbody
    - @movies.each do, movie, %tr
        %td
          %strong=movie.title

Use the search object to display further narrowing options to the user

- filter = @search.filter(:genre)
.col-md-4
  .filter
    .filter-title= filter.name
    .filter-values
      %ul.selected
        - filter.selected.each do, genre, %li= link_to genre.name, filter.remove(genre).path
      %ul.selectable
        - filter.facet.reject(&:selected).each do, facet_value, - genre = facet_value.entity
          %li
            = link_to genre.name, filter.add(genre).path
            %span.count= "(#{facet_value.count})"

API

Base class

To create a custom search subclass FortyFacets::FacetSearch.

class MySearch
  model 'MyActiveRecordModel' # replace this with an class name from your models folder
end

Available declaration methods, keyword, options, ---------, ---------------, -------------------------------------------------------------------------------------------------------------------------, text, prefix:true, creates a filter to limit search result to entities containing the filter value in the given field, scope, creates a filter to limit search result to entities matching the scope with the given name, facet, creates a facetted filter on the specified model attribute (attribute or belongs_to), range, creates a range filter (param format 'FROM - TO') limiting result to entities with values in that range, orders, takes a hash mapping a label to an argument that the active record order method can be called with to sort the result, custom, doesnt affect the query directly, just handles the request param. access via @search.filter(:custom_filter).set(..) /@search.filter(:custom_filter).value, ## FAQ

What kind of associations can be searched/filtered for?

At the moment you can facet for entities mapped via a standard belongs_to or has_and_belongs_to association.

Contributing

  1. Fork it ( http://github.com/fortytools/forty_facets/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Overview

Name With OwnerFortySource/forty_facets
Primary LanguageRuby
Program languageRuby (Language Count: 1)
Platform
License:MIT License
Release Count27
Last Release Namev0.2.1 (Posted on 2022-06-09 23:41:15)
First Release Namev0.0.1 (Posted on 2014-05-15 18:19:48)
Created At2014-05-15 11:33:29
Pushed At2022-12-02 19:04:21
Last Commit At2022-12-02 14:04:21
Stargazers Count263
Watchers Count17
Fork Count21
Commits Count99
Has Issues Enabled
Issues Count15
Issue Open Count8
Pull Requests Count11
Pull Requests Open Count0
Pull Requests Close Count1
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private
To the top