Coder Social home page Coder Social logo

jhund / filterrific Goto Github PK

View Code? Open in Web Editor NEW
907.0 25.0 124.0 1.02 MB

Filterrific is a Rails Engine plugin that makes it easy to filter, search, and sort your ActiveRecord lists.

Home Page: http://filterrific.clearcove.ca

License: MIT License

Ruby 87.84% JavaScript 12.16%
filter ruby-on-rails activerecord

filterrific's People

Contributors

aditya-cherukuri avatar ayaman avatar bbucek avatar blaedj avatar coffeejunk avatar edwardmp avatar euxx avatar ferdinandrosario avatar fniscak avatar geraintwhite avatar iiwo avatar jhund avatar korol-sas avatar mstate avatar nikola-airshaper avatar olegantonyan avatar petergoldstein avatar pnomolos avatar scottkolo avatar sebboh avatar tinyfive avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

filterrific's Issues

Dynamic filters on hstore params?

@jhund I'm having some trouble wrapping my head around how I would do this. I want my model to have an hstore with user-configurable fields. I then want the user to be able to filter on each field. Can it work?

Thanks!

Ability to pass filterrific form options through on the filterrific model.

I often find myself wishing I had an easy way of grouping all the form options for all of filterrific's select boxes, and have taken to doing the following:

@filterrific = Filterrific.new(ModelClass, params[:filterrific])
class << @filterrific
    attr_accessor :options
end
@filterrific.options = {
    category_ids: ModelClass.joins(:category).distinct.pluck('categories.id', 'category.name'),
    # A bunch of other filter options here
}

Then in the view:

<%= f.select :with_category_id, @filterrific.options[:category_ids], 'data-placeholder' => 'Category' %>

Rather than having to have a @category_ids instance variable, and whatever other instance variables are needed. Would you be open to something like this making it into core?

If so I'll put a PR together :)

ERROR: undefined method `empty?' for nil:NilClass

Having trouble getting this gem to work. I am getting the error "ERROR: undefined method `empty?' for nil:NilClass", it seems like the problem comes from the f.select in my form.

I have attached the relevant sections below. I have been trying to get this gem to work all day with no luck. Great documentation, but just can't get it to work.

My Application model:

  class Application < ActiveRecord::Base
  belongs_to :user
  belongs_to :project

filterrific(
  default_settings: {  sorted_by: 'created_at_desc' },
  filter_names: %w[
    with_angelbacker_id
    sorted_by
  ]
)

scope :sorted_by, lambda { |sort_option|
  # extract the sort direction from the param value.
  direction = (sort_option =~ /desc$/) ? 'desc' : 'asc'
  case sort_option.to_s
  when /^created_at_/
    # Simple sort on the created_at column.
    # Make sure to include the table name to avoid ambiguous column names.
    # Joining on other tables is quite common in Filterrific, and almost
    # every ActiveRecord table has a 'created_at' column.
    order("applications.created_at desc")
  else
    raise(ArgumentError, "Invalid sort option: #{ sort_option.inspect }")
  end
}

scope :with_angelbacker_id, lambda { |flag|
   return nil  if 0 == flag # checkbox unchecked
   where(:angelbacker => flag)
 }  


 def self.options_for_sorted_by
  [
    ['Angelbacker', 'created_at_desc']
  ]
 end
 end

My Project controller model:

     @filterrific = Filterrific.new(Application, params[:filterrific] || session[:filterrific_applications])
     @applications = Application.filterrific_find(@filterrific).page(params[:page])
     session[:filterrific_applications] = @filterrific.to_hash

    respond_to do |format|
       format.html
       format.js
    end

My Project view:

<%= form_for @filterrific do |f| %>
    <div>
      Angelbacker
      <%= f.select(
        :with_angelbacker_id,
        @filterrific.select_options[:with_angelbacker],
        { include_blank: '- Any -' }
      ) %>
      <%# See below for the Country.options_for_select presenter method %>
    </div>
    <div>
      Sorted by
      <%= f.select(:sorted_by, @filterrific.select_options[:sorted_by]) %>
      <%# See below for the Student.options_for_sorted_by presenter method %>
    </div>
    <div>
      <%= link_to(
        'Reset filters',
        reset_filterrific_applications_path,
      ) %>
    </div>
    <%# add an automated spinner to your form when the list is refreshed %>
    <%= render_filterrific_spinner %>
  <% end %>

  <%= render(
    'list',
    locals: { applications: @applications }
  ) %>

Merge?

Can you suggest a way to merge two mutually exclusive scopes using filterrific? No problem utilizing individual filters/scopes, but I'd like to have at the end of the scope chain .merge(final_named_scope)

Always cast filter values into `int` considered harmful

In the ParamSet class when the value looks like an int we cast it as an int

ex

[1] > condition_filterrific_params { 'filter_array_int' => %w[1 2 3], 'filter_int' => '42' }
=> { 'filter_array_int' => [1, 2, 3], 'filter_int' => 42 }

which is fine most of the time.

however this might not always be what we want, for example, i want to look for a basic search on :phone in a User activerecord, I might do:

class User < ActiveRecord::Base
    scope :with__phone__ilike, ->(value) { where("phone ILIKE ?", "%#{value}%") }
end

# let's say in db we have the following users
# User(phone: '12346789')
# User(phone: '12340067')

class SearchController < ActionController
    def search_phone
        filt = initialize_filterrific(User, params)
        users = User.filterrific_find(filt)
        render json: users.pluck(:phone)
    end
end

# calling the route with: params = { 'with__phone__ilike' => '067' }
# will sanitize the filter to { 'with__phone__ilike' => 67 }
# and returns false positive => ['12346789', '12340067']

in that case the leading 0 was important in the filter value and was filter out because it was casted as int.

Same problem occurs if it appears in an array

I think we might expect information not to be dropped (in that case the leading zero)
something like

[1] > condition_filterrific_params { 'filter_array_int' => %w[1 2 3 03], 'filter_not_quite_int' => '042', 'filter_int' => '42' }
=> { 'filter_array_int' => [1, 2, 3, '03'], 'filter_not_quite_int' => '042', 'filter_int' => 42 }

this could be achieved by using a different regex such as /^[1-9]\d*$/. Replacing that code by

def condition_filterrific_params(fp)
      fp.each do |key, val|
        case
        when val.is_a?(Proc)
          # evaulate Procs
          fp[key] = val.call
        when val.is_a?(Array)
          # type cast integers in the array
          fp[key] = fp[key].map { |e| e =~ /^[1-9]\d*$/ ? e.to_i : e }
        when val =~ /^[1-9]\d*$/
          # type cast integer
          fp[key] = fp[key].to_i
        end
      end
      fp
    end
``

Check if filters are set in the view

I was wondering if there's a way to check if the filters are set in the view. I'd like to provide a hint to my users that the view is currently filtered.

No form displayed

Hi,

New to filterrific, I want to display a filter form.
Base on rails 4.2 (ruby 2.1) and erb, the form seem not to be displayed (neither visible nor in the DOM) when I add this into my view

<% form_for @filterrific, html: {id: 'filterrific_filter'} do |f| %>
  <select>
    <% @filterrific.select_options[:per_event].each do |name, id| %>
     <option value="<%=id%>"><%=name%></option>
    <% end %>
  </select>
<% end %>

even this

<% form_for @filterrific, html: {id: 'filterrific_filter'} do |f| %>
  <select>
    <%= f.select :per_event, @filterrific.select_options[:per_event] %>
  </select>
<% end %>

only this

<select>
    <% @filterrific.select_options[:per_event].each do |id,name| %>
      <option value="<%=id%>"><%=name%></option>
    <% end %>
  </select

could diplay my select.

select_options[:per_event] contains an array of element I want to filter with

I could not find any doc with rails 4, am I missi,ng something ?

Regards,

reset_filterrific_url() should respect the :as option of the form

If you use:

<%= form_for_filterrific @filterrific, as: :filter do |f| %>
<% end %>

the params prefix will be filter but the reset_filterrific_url() uses the default filterrific one:

?filterrific[reset_filterrific]=true

instead of:

?filter[reset_filterrific]=true

I think that an :as option in the helper would suffice.

undefined method `filterrific'

Keep getting "undefined method" error for my model.
Though it worked for a while. Only thing I did after was install searchkick. Though I uninstalled both and reinstalled only filterrific, to no avail.

I'm using rails 4, filterrific 1.3.1 and ruby 2.0.0

Error message:
undefined method `filterrific' for #Class:0x007fb710eee7a0

Extracted source (around line #2):
class Listing < ActiveRecord::Base
filterrific(
default_settings: { sorted_by: 'created_at_desc' },
filter_names: [
:sorted_by,
:search_query,

Here's the stack trace:
activerecord (4.1.4) lib/active_record/dynamic_matchers.rb:26:in method_missing' app/models/listing.rb:2:inclass:Listing'
app/models/listing.rb:1:in <top (required)>' activesupport (4.1.4) lib/active_support/dependencies.rb:443:inload'
activesupport (4.1.4) lib/active_support/dependencies.rb:443:in block in load_file' activesupport (4.1.4) lib/active_support/dependencies.rb:633:innew_constants_in'
activesupport (4.1.4) lib/active_support/dependencies.rb:442:in load_file' activesupport (4.1.4) lib/active_support/dependencies.rb:342:inrequire_or_load'
activesupport (4.1.4) lib/active_support/dependencies.rb:480:in load_missing_constant' activesupport (4.1.4) lib/active_support/dependencies.rb:180:inconst_missing'
activesupport (4.1.4) lib/active_support/inflector/methods.rb:238:in const_get' activesupport (4.1.4) lib/active_support/inflector/methods.rb:238:inblock in constantize'
activesupport (4.1.4) lib/active_support/inflector/methods.rb:236:in each' activesupport (4.1.4) lib/active_support/inflector/methods.rb:236:ininject'
activesupport (4.1.4) lib/active_support/inflector/methods.rb:236:in constantize' activesupport (4.1.4) lib/active_support/core_ext/string/inflections.rb:66:inconstantize'
cancan (1.6.10) lib/cancan/controller_resource.rb:147:in resource_class' cancan (1.6.10) lib/cancan/controller_resource.rb:187:inresource_base'
cancan (1.6.10) lib/cancan/controller_resource.rb:77:in load_collection?' cancan (1.6.10) lib/cancan/controller_resource.rb:33:inload_resource'
cancan (1.6.10) lib/cancan/controller_resource.rb:25:in load_and_authorize_resource' cancan (1.6.10) lib/cancan/controller_resource.rb:10:inblock in add_before_filter'
activesupport (4.1.4) lib/active_support/callbacks.rb:440:in instance_exec' activesupport (4.1.4) lib/active_support/callbacks.rb:440:inblock in make_lambda'
activesupport (4.1.4) lib/active_support/callbacks.rb:160:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:160:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:149:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:149:inblock in halting_and_conditional'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:166:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:229:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:229:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:229:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:229:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:166:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:166:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:166:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:86:in call' activesupport (4.1.4) lib/active_support/callbacks.rb:86:inrun_callbacks'
actionpack (4.1.4) lib/abstract_controller/callbacks.rb:19:in process_action' actionpack (4.1.4) lib/action_controller/metal/rescue.rb:29:inprocess_action'
actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:31:in block in process_action' activesupport (4.1.4) lib/active_support/notifications.rb:159:inblock in instrument'
activesupport (4.1.4) lib/active_support/notifications/instrumenter.rb:20:in instrument' activesupport (4.1.4) lib/active_support/notifications.rb:159:ininstrument'
actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:30:in process_action' actionpack (4.1.4) lib/action_controller/metal/params_wrapper.rb:250:inprocess_action'
searchkick (0.8.3) lib/searchkick/logging.rb:107:in process_action' activerecord (4.1.4) lib/active_record/railties/controller_runtime.rb:18:inprocess_action'
actionpack (4.1.4) lib/abstract_controller/base.rb:136:in process' actionview (4.1.4) lib/action_view/rendering.rb:30:inprocess'
actionpack (4.1.4) lib/action_controller/metal.rb:196:in dispatch' actionpack (4.1.4) lib/action_controller/metal/rack_delegation.rb:13:indispatch'
actionpack (4.1.4) lib/action_controller/metal.rb:232:in block in action' actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:incall'
actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:in dispatch' actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:50:incall'
actionpack (4.1.4) lib/action_dispatch/journey/router.rb:71:in block in call' actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:ineach'
actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in call' actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:678:incall'
rack-pjax (0.8.0) lib/rack/pjax.rb:12:in call' warden (1.2.3) lib/warden/manager.rb:35:inblock in call'
warden (1.2.3) lib/warden/manager.rb:34:in catch' warden (1.2.3) lib/warden/manager.rb:34:incall'
rack (1.5.2) lib/rack/etag.rb:23:in call' rack (1.5.2) lib/rack/conditionalget.rb:25:incall'
rack (1.5.2) lib/rack/head.rb:11:in call' remotipart (1.2.1) lib/remotipart/middleware.rb:27:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/params_parser.rb:27:in call' actionpack (4.1.4) lib/action_dispatch/middleware/flash.rb:254:incall'
rack (1.5.2) lib/rack/session/abstract/id.rb:225:in context' rack (1.5.2) lib/rack/session/abstract/id.rb:220:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/cookies.rb:560:in call' activerecord (4.1.4) lib/active_record/query_cache.rb:36:incall'
activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:621:in call' activerecord (4.1.4) lib/active_record/migration.rb:380:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:29:in block in call' activesupport (4.1.4) lib/active_support/callbacks.rb:82:inrun_callbacks'
actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:27:in call' actionpack (4.1.4) lib/action_dispatch/middleware/reloader.rb:73:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/remote_ip.rb:76:in call' actionpack (4.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:17:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/show_exceptions.rb:30:in call' railties (4.1.4) lib/rails/rack/logger.rb:38:incall_app'
railties (4.1.4) lib/rails/rack/logger.rb:20:in block in call' activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:inblock in tagged'
activesupport (4.1.4) lib/active_support/tagged_logging.rb:26:in tagged' activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:intagged'
railties (4.1.4) lib/rails/rack/logger.rb:20:in call' actionpack (4.1.4) lib/action_dispatch/middleware/request_id.rb:21:incall'
rack (1.5.2) lib/rack/methodoverride.rb:21:in call' rack (1.5.2) lib/rack/runtime.rb:17:incall'
activesupport (4.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in call' rack (1.5.2) lib/rack/lock.rb:17:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/static.rb:64:in call' rack (1.5.2) lib/rack/sendfile.rb:112:incall'
railties (4.1.4) lib/rails/engine.rb:514:in call' railties (4.1.4) lib/rails/application.rb:144:incall'
rack (1.5.2) lib/rack/lock.rb:17:in call' rack (1.5.2) lib/rack/content_length.rb:14:incall'
rack (1.5.2) lib/rack/handler/webrick.rb:60:in service' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/webrick/httpserver.rb:138:inservice'
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/webrick/httpserver.rb:94:in run' /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/webrick/server.rb:295:inblock in start_thread'

Please let me know if there's any more information I can provide. I'm a noob.

Exporting to csv using filterrific

I am trying to export the filtered data to a .csv file but all I get is all the records from the database. here is my link_to.
<%= link_to "Exporter", users_path(:format => :csv, :filterrific => params[:filterrific]) %>
Can't figure out How to get the filtered params...

Any idea would be great

Thanks

Passing filter parameters in a url?

I hoping to use this gem to replace our current filtering system because it looks really awesome. The one thing that we need to be able to do is pass filter parameters in to that page through a url. That way we can send a user to the exact set of results they may be looking for. Is there a way to add ?search_query=Chris or whatever to the end of the page url?

Chainning the existing scopes with Filterrific doesn't work when the filter is empty.

Chainning the existing scopes with Filterrific doesn't work when the filter is empty.

Here is a simple example:

# Assuming a feedback model having a rating (integer) column
class Feedback < ActiveRecord::Base
  filterrific(filter_names: [:with_rating])
  scope :no_low_rating, -> { where('rating > ?', 2) }
  scope :with_rating, ->(keys) { where(rating: [*keys.to_s.split(',')]) }
end

# When there is a filter
filter = Filterrific.new(Feedback, with_rating: 2)
# This will work
Feedback.no_low_rating.filterrific_find(filter)
# When there is no filter
filter = Filterrific.new(Feedback, {})
# This won't work, it'll give me the ActiveRecord class Feedback
Feedback.no_low_rating.filterrific_find(filter)
# This will work but is damn ugly
Feedback.filterrific_find(filter).all.scoping { Feedback.no_low_rating }

A fix seems to be the following (ruby 2.0.0 rails 4.1)

module Filterrific
  module ActiveRecordExtension
    def filterrific_find(filterrific_param_set)
      unless filterrific_param_set.is_a?(Filterrific::ParamSet)
        raise(ArgumentError, "Invalid Filterrific::ParamSet: #{ filterrific_param_set.inspect }")
      end

      # set initial ar_proxy to including class
      ar_proxy = self.all  # CHANGED `self` TO `self.all`

      # apply filterrific params
      self.filterrific_filter_names.each do |filter_name|
        filter_param = filterrific_param_set.send(filter_name)
        next if filter_param.blank? # skip blank filter_params
        ar_proxy = ar_proxy.send(filter_name, filter_param)
      end

      ar_proxy
    end
  end
end

It's seems to work for the other cases:

  • when the filter isn't empty,
  • or when you apply the second scope afterward

Search button

Hi, first of all I'd like like to thank you for this great gem. I'm actually looking for a way to perform searches with a search button only. I have too many input fields and a google maps in my _list partial, having a new request each time a select input has been changed isn't a good thing I guess. How can I implement a button ? Thanks in advance for your answer

undefined method `filterrific_find' for Filterrific:Module

I have no idea why I'm getting this error. Below is my code.

Leads Controller (There's some extra code in here that needs to be cleaned up, but I just pasted it all.

class LeadsController < ApplicationController
def index
    @user = current_user
    @leads = Lead.where(reviewed: true).order(:id).page(params[:page])
    @filterrific = Filterrific.new(Lead, params[:filterrific] || session[:filterrific_leads])
    @filterrific.select_options = { with_action_type_id: Actiontype.options_for_select }
    @user_leads = @user.leads.filterrific_find(@filterrific).page params[:page]
    session[:filterrific_leads] = @filterrific.to_hash

    @actiontypes = Actiontype.all
    @nonleadactions = Nonleadaction.all
    @inquiryreasons = Reasoninquiry.all
    @actual_leads = Lead.where(:reasoninquiry_id => [1, 2, 3])
    @bymonthleads = @actual_leads.group_by { |lead|   lead.created_at.beginning_of_month.strftime("%B")}

    respond_to do |format|
        format.html
        format.js
    end
end

def reset_filterrific
    session[:filterrific_leads] = nil
    redirect_to action: :index
end

Lead Model

class Lead < ActiveRecord::Base
filterrific(
    default_settings: { sorted_by: 'actiontype_id_desc' },
    filter_names: [
      :sorted_by,
      :with_action_type_id,
      :with_inquiry_type_id
    ]
)


belongs_to :user
has_one :actiontype
has_one :reasoninquiry
has_one :nonleadaction

scope :sorted_by, lambda { |actiontypes|
    order("leads.created_at desc")
}


scope :with_action_type_id, lambda { |actiontypes|
    where(actiontype_id: [*actiontypes])
    where(reviewed: true)
}

scope :with_inquiry_type_id, lambda { |inquiry_type_ids|
# Filters students with any of the given country_ids
}




def self.filter_by_reviewed_status(status)
  case status
  when nil     then scoped
  when 'true'  then where(reviewed: true)
  when 'false' then where(reviewed: false)
  end
end

end

index.html.erb (again, messy and needs to be cleaned up, but I don't know if something in here is messing it up)

                     <%= form_for @filterrific do |f| %>
                        <div class="row-fluid">
                            <div class="widget-half span6">
                                <label>Start Date:</label>
                                <input class="filters" type="text" id="startDate" name="sd" value="30 days ago">
                            </div>
                            <div class="widget-half  span6">
                                <label>End Date:</label>
                                <input class="filters" type="text" id="endDate" name="ed" value="today" />  
                            </div> 
                        </div>
                        <div class="form-actions">
                            <div id="report-callback"></div>
                            <div id="select-action">
                                <input type="submit" class="btn btn-green btn-large btn-wide pull-right" value="Generate Report"/>
                            </div>
                            <div id="email-popup" style="display: none">
                                <p>We'll email this to you in a few minutes, where should we send it (separate Emails by commas)?</p>
                                <textarea name="emails" class="input-block-level"></textarea>
                                <input type="button" class="btn btn-green btn-large btn-wide pull-right"  value="Send Report" id="send-report"/>
                                <input type="button" class="btn btn-grey btn-large btn-wide pull-left" value="Cancel" id="cancel-report"/>
                            </div>
                            <% @filterrific.select_options[:with_action_type_id].each do |c| %>
                                <%= check_box_tag("filterrific[with_action_type_id][]",c) %>
                                <%=h c %>
                            <% end %>
                            <%= f.select :with_action_type_id,       @filterrific.select_options[:with_action_type_id], include_blank: true %>
                        </div>
                    <% end %>

Actiontype model

belongs_to :lead

def self.options_for_select
    order('action_type').map { |e| [e.action_type, e.id] }
end   

What runs in the server log when I do the request:

    Started GET "/leads" for 127.0.0.1 at 2014-08-06 16:55:20 -0400
 Processing by LeadsController#index as HTML
  ←[1m←[36mUser Load (0.0ms)←[0m  ←[1mSELECT "users".* FROM "users" WHERE "users
"."id" = ? LIMIT 1←[0m  [["id", 3]]
  ←[1m←[35mActiontype Load (0.0ms)←[0m  SELECT "actiontypes".* FROM "actiontypes
" ORDER BY action_type
Completed 500 Internal Server Error in 5ms

 ArgumentError (wrong number of arguments (0 for 1)):
   app/controllers/leads_controller.rb:8:in `index'


 Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-4.0.2
/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.0ms)
  Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-4.0.2
/lib/action_dispatch/middleware/templates/rescues/_trace.erb (2.0ms)
Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-4.0.2
/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.0
ms)
 Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-4.0.2
/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues
/layout (29.0ms)

Initial DB setup question

Hi,

I want to use filterrific on a new project but I want to make sure that I set the database up correctly.

I want my users to be able to input which language(s) they speak. ex: User 1 speaks English, French, Spanish.

I want people to be able to filter the search using multiple languages. Ex: find all users that speak both English and Spanish. I figured that would be done via a drop-down with check boxes.

What is the best way to set this up so that search/filtering is as fast as possible? Should each language be in a separate field ex: language_1 contains English, language_2 contains Spanish, etc. or can I save the languages in an array under a single field ex: language contains [English, Spanish, French]

Thanks for any feedback. I am just building out the app and don't want to get too far down a path that might make things slow.

Support for STI (Single Table Inheritance)

Let's say you have two ActiveRecord class with one inheriting another

ex:

class WorkaholicDaddy < ActiveRecord::Base
    filterrific(available_filters: [:millionaire, :sillicon_valley])
end

class DigitalBoy < WorkaholicDaddy
    filterrific(available_filters: [:botox_injection, :fake_nails])
end

puts WorkaholicDaddy.filterrific_available_filters
# => botox_injection
# => fake_nails

puts DigitalBoy.filterrific_available_filters
# => botox_injection
# => fake_nails

Then the filterific_available_filters of the lastest loaded class will override the first one.

That's not great.
This is due to the fact that the filterrific_available_filters is a class variable (see https://github.com/jhund/filterrific/blob/master/lib/filterrific/active_record_extension.rb#L22-L23). If it was a class instance variable it would work fine.

see https://stackoverflow.com/questions/15773552/ruby-class-instance-variable-vs-class-variable

Errror message "wrong number of arguments"

I copied the sample and updated the sample code and adapted it.

Using filterrific 1.2.0

in location.rb

  filterrific(
    :default_settings => { :sorted_by => 'name_asc' },
    :filter_names => %w[
                    sorted_by
                    search_query
                    with_zone_id
                  ] 
  )

in location_controller.rb

  def index
    @filterrific = Filterrific.new(Location, params[:filterrific])
    @locations = Location.filterrific_find(@filterrific).page(params[:page])

    respond_to do |format|
      format.html
      format.js
    end

  end

in index.html.erb

 <%= form_for @filterrific do |f| %>

I get an error message for the above line

"where line #3 raised:
wrong number of arguments (0 for 1)"

I cannot get to the root cause for this problem. Any help appreciated

Filter by nil value

I use multiple select for filter by status and I would like to add option "by blank'.
But when I add ['by blank', nil] to collection then in html i have blank value in option element.

I have workaround solution, I add ['by blank', 'nil'] to collection and in scope replace 'nil' to nil.
scope:

  scope :with_status_id, lambda { |status_ids|
    ids = status_ids.dup 
    idx = status_ids.index { |o| o == 'nil' }
    ids[idx] = nil unless idx.nil?
    where(status_id: [*ids]) unless ids == [""]
  }

Is there any better way to filter by nil value?

There is no doc for scoping habtm relation

Could we please have some documentation on how to scope an habtm relation? The examples work with has_many_through, but I cannot find any help to scope habtm.

For example on a bloglike application, where the post model has and belongs to many tags, I would like to have some examples on filtering posts by tags or by tags category.

Is there a way to do that?

Filterrific not working properly with multiple set true

Hello,

I'm not sure if this is how Filterrific works or if I'm doing something wrong.

I have two select tags set as multiple: true . When filterrific submits the data through ajax it takes the value from all the selects, which is fine. But if one of them is untouched/default it takes the value as nil .. which causes the results to return empty.

screen shot 2014-10-30 at 2 42 40 pm

^ No matter if I touch the client select or not, it submits as nil .

If both selects are normal, with single value, works fine. The issue only happens when it has multiple values. Even by selecting - Any - as default doesn't return as it should.

I basically want to be able to search all my projects that have status Live from all clients.

undefined method `empty?' for nil:NilClass

Hey, I keep getting this error from my select field.
Here are snippets of my code:

offer.rb
belongs_to :client
scope :with_client_id, -> { where(:client_id => client.id) }
scope :with_status, -> { where(:status => status) }

filterrific(
filter_names: [
:with_client_id,
:with_status,
:with_created_at_gte
]
)

offers_controller.rb

def index
@filterrific = Filterrific.new( Offer, params[:filterrific] || session[:filterrific_offers])
@offers = Offer.filterrific_find(@filterrific)
respond_to do |format|
format.html
format.js
end
end

index.html.erb

<%= form_for @filterrific do |f| %>

Search <%# give the search field the 'filterrific-periodically-observed' class for live updates %> <%= f.text_field(:search_query, class: 'filterrific-periodically-observed') %>
Created_at <%= f.text_field(:with_created_at_gte, class: 'js-datepicker') %>
Client <%= f.select(:with_client_id, @filterrific.select_options[:with_client_id]) %>
... <% end %>

Can you please give me a hint on why this error occurs?
Thanks!

sort by foreign key value in sqlite not working

Hi,

I'm using the demo source with sqlite3, and I don't get the sort-by-country-name working. I get the following error.

SELECT  "students".* FROM "students" WHERE "students"."country_id" = 6  ORDER BY LOWER(countries.name) asc LIMIT 10 OFFSET 0
SQLite3::SQLException: no such column: countries.name: SELECT  "students".* FROM "students" WHERE "students"."country_id" = 6  ORDER BY LOWER(countries.name) asc LIMIT 10 OFFSET 0
  Rendered students/_list.html.haml (8.3ms)
  Rendered students/index.js.erb (10.9ms)
Completed 500 Internal Server Error in 21ms

Is this a sqlite problem? How do I fix this?

Thanks!

"Filter by (non) existence of has_many association" has wrong condition

At least under Rails 4.2.0 it is wrong. In the documentation under http://filterrific.clearcove.ca/pages/active_record_scope_patterns.html#filter_by_existence_has_many you say to use

scope :with_comments, lambda {
  where(
    'EXISTS (SELECT 1 FROM students, comments WHERE students.id = comments.student_id)'
  )
}

which "finds all students who have posted at least one comment."

This is not true, the code is translated into

SELECT "students".* FROM "students" WHERE ( EXISTS (SELECT 1 from students, comments WHERE students.id = comments.student_id)

So the WHERE-predicate is independent from the row of the outer "students" column and this way you get either the whole students table, if there is at least one student with a comment, or else an empty result set.

A fix for this would be to use

scope :with_comments, lambda {
  where(
    'EXISTS (SELECT 1 FROM  comments WHERE students.id = comments.student_id)'
  )
}

(so without the additional "FROM students" in the inner query) which translates to

SELECT "students".* FROM "students" WHERE ( EXISTS (SELECT 1 from comments WHERE students.id = comments.student_id)

Analogous for the "non existence" part.

Direct to filter page with params

I have two views. The first one runs filterrific with a text input and a select input. The second view has a text input and a button. I want the button to link to the first view with the input value passed to the filter. However, when I set the initial value of the filter input, filterrific observer doesn't detect it. I need to update the text input again to make the page show the correct result.

<%= f.text_field(:search_query, :value => params[:q], class: 'filterrific-periodically-observed typeahead') %>

Scopes seem to be overwriting eachother

Hi There,

I'm trying to set up a filtering/search engine using Filterrific.

So that you can get an idea of how the front-end operates:

screen shot 2014-06-24 at 9 08 58 am

Here is my model:

class Supplier < ActiveRecord::Base

  # Supplier Admin Logins
  devise :database_authenticatable, :timeoutable

  # Search Engine
  searchkick autocomplete: ['name']

  # Paperclip
  has_attached_file :image, :styles => { :full => "738x232#", :medium => "157x117#", :thumb => "200x85#" }, :default_url => "/assets/no-image-logo.png"
  process_in_background :image, :processing_image_url => "/assets/image_processing.jpg"

  # Validations
  validates :email, :location, :phone, :website, :name, :available, :about, presence: true

  # Associations
  has_many :products, primary_key: :id, foreign_key: :supplier_id
  has_many :supplier_images, primary_key: :id, foreign_key: :supplier_id, dependent: :destroy
  has_many :supplier_comments, primary_key: :id, foreign_key: :supplier_id, dependent: :destroy

  has_many :supplier_features, primary_key: :id, foreign_key: :supplier_id

  has_many :supplier_enquiries, primary_key: :id, foreign_key: :supplier_id

  # Allowed Attributes
  attr_accessible :email, :location, :password, :phone, :website, :name, :image, :available, :contact_email, :facebook, :twitter, :pinterest, :board_limit, :is_authorized, :is_premium, :about, :supplier_images_attributes
  accepts_nested_attributes_for :supplier_images

  # Filterrific Filtering
  filterrific(
    :default_settings => { :sorted_by => 'name_asc' },
    :filter_names => [
      :sorted_by,
      :search_query,
      :with_categories,
      :with_locations
    ]
  )

  scope :sorted_by, lambda { |sort_option|
    # extract the sort direction from the param value.
    direction = (sort_option =~ /desc$/) ? 'desc' : 'asc'

    case sort_option.to_s
    when /^name/
      # Simple sort on the created_at column.
      # Make sure to include the table name to avoid ambiguous column names.
      # Joining on other tables is quite common in Filterrific, and almost
      # every ActiveRecord table has a 'created_at' column.
      order("suppliers.name #{ direction }")
    when /^created_at_/
      order("suppliers.created_at #{ direction }")
    else
      raise(ArgumentError, "Invalid sort option: #{ sort_option.inspect }")
    end
  }

  scope :search_query, lambda { |query|
    # Searches the students table on the 'first_name' and 'last_name' columns.
    # Matches using LIKE, automatically appends '%' to each term.
    # LIKE is case INsensitive with MySQL, however it is case
    # sensitive with PostGreSQL. To make it work in both worlds,
    # we downcase everything.
    return nil  if query.blank?

    supplier_ids = self.search(query).map(&:id)

    return nil if supplier_ids.empty?

    where(id: supplier_ids)
  }

  scope :with_categories, lambda { |category_ids|

    return nil  if category_ids.blank?

    formatted_category_ids = []

    category_ids.each do |key, value|
       formatted_category_ids << key.to_i if value.to_i == 1
    end

    return nil  if formatted_category_ids.blank?


    # Get all Suppliers that have Products in the supplied Categories
    @suppliers = Supplier.joins(:products).where(products: { category_id: formatted_category_ids}).uniq!

    # Array of valid supplier ids
    valid_suppliers = []

    # Loop over all the suppliers
    @suppliers.each do |s|

      catch(:invalid_supplier) do

        # Loop over each category id
        formatted_category_ids.each do |ci|
          # If supplier does not have a product in this category,
          # throw :invalid_supplier symbol to prevent adding supplier to array
          throw :invalid_supplier if !s.products.where(category_id: ci).any?
      end

    # If symbol has not been thrown, save the suppliers id
    valid_suppliers << s.id

  end
end

return nil if valid_suppliers.empty?

# Return relation of suppliers
where(id: valid_suppliers)

}

scope :with_locations, lambda { |location_ids|

  return nil  if location_ids.blank?

  formatted_location_ids = []

  location_ids.each do |key, value|
    formatted_location_ids << key.to_i if value.to_i == 1
  end

  return nil  if formatted_location_ids.blank?

  # Get all products from this supplier, in this location
  @suppliers = Supplier.joins(products: :locations).where(locations: {id: formatted_location_ids}).uniq!

  valid_suppliers = []

  # Loop over each supplier and make sure they have at least one product in every location
  @suppliers.each do |s|

    catch(:invalid_supplier) do

      # Loop over each category id
      formatted_location_ids.each do |li|
        # If supplier does not have a product in this category,
        # throw :invalid_supplier symbol to prevent adding supplier to array
        throw :invalid_supplier if !s.products.joins(:locations).where('locations.id = ?', li).any?
      end

      # If symbol has not been thrown, save the suppliers id
      valid_suppliers << s.id

    end
  end

  return nil  if valid_suppliers.empty?

  # Return relation
  where(id: valid_suppliers)

}

def self.options_for_sorted_by
  [
    ['Name Ascending (A-Z)', 'name_asc'],
    ['Name Descending (Z-A)', 'name_desc'],
    ['Recently Joined', 'created_at_desc']
  ]
end

def active_products
  self.products.where(paused: false)
end
end`

and my Controller:

`class SuppliersController < ApplicationController
  # GET /suppliers
  # GET /suppliers.json

  def index
    @filterrific = Filterrific.new(
    Supplier,
      params[:filterrific] || session[:filterrific_suppliers]
    )

    @filterrific.select_options = {
      sorted_by: Supplier.options_for_sorted_by,
    }   

    @suppliers = Supplier.filterrific_find(@filterrific).paginate(page: params[:page], per_page: 15)

    session[:filterrific_suppliers] = @filterrific.to_hash
  end

  def reset_filterrific
    # Clear session persistence
    session[:filterrific_suppliers] = nil
    # Redirect back to the index action for default filter settings.
    redirect_to :action => :index
  end

  def search
    if params[:query].present?
      @suppliers = Supplier.search(params[:query], page: params[:page])
      @supplier = @suppliers[0].name == "Inspiration from Real Weddings" ? @suppliers[1] :      @suppliers[0]
    else
      @suppliers = Supplier.all
    end
  end

  def autocomplete
    render json: Supplier.search(params[:query], autocomplete: true, limit: 10).map(&:name)
  end

  def show
    @supplier = Supplier.find(params[:id])
    @supplier_comment = SupplierComment.new
    @supplier_comments = @supplier.supplier_comments.order('created_at DESC')

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @supplier }
    end
  end
end`

When I use the filters individually, it works fine. But after doing a search and then filtering categories, it shows results that the search alone wouldn't show.

syntax error

I jus copy n paste from your example, but I have an syntax error in this line: }.join(' AND '),
I'm relatively new in ruby on rails. I hope you can help me :)

scope :search_query, lambda { |query|

Searches the students table on the 'first_name' and 'last_name' columns.

Matches using LIKE, automatically appends '%' to each term.

LIKE is case INsensitive with MySQL, however it is case

sensitive with PostGreSQL. To make it work in both worlds,

we downcase everything.

return nil if query.blank?

condition query, parse into individual keywords

terms = query.downcase.split(/\s+/)

replace "_" with "%" for wildcard searches,

append '%', remove duplicate '%'s

terms = terms.map { |e|
(e.gsub('_', '%') + '%').gsub(/%+/, '%')
}

configure number of OR conditions for provision

of interpolation arguments. Adjust this if you

change the number of OR conditions.

num_or_conds = 2
where(
terms.map { |term|
"(LOWER(students.first_name) LIKE ? OR LOWER(students.last_name) LIKE ?)"
}.join(' AND '),
*terms.map { |e| [e] * num_or_conds }.flatten
)
}

ArgumentError executing search.

I am getting an argument error when the search is submitted and can't figure out exactly what's wrong.

Thanks for any help (info and trace below)


ENV INFO:

filterrific version: 1.3.1
rails version: 4.1.4
ruby: 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin12.0]


IN MODEL:

filterrific(
filter_names: [
:name
]
)


CONTROLLER:

class CoursesController < ApplicationController

def index
@filterrific = Filterrific.new(Course, params[:filterrific])
@courses = Course.filterrific_find(@filterrific).page(params[:page])
respond_to do |format|
format.html
format.js
end
end

end


RAILS LOG:

Started GET "/courses/index?utf8=%E2%9C%93&filterrific%5Bname%5D=p&=1411342345879" for 127.0.0.1 at 2014-09-21 16:43:24 -0700
Processing by CoursesController#index as JS
Parameters: {"utf8"=>"✓", "filterrific"=>{"name"=>"p"}, "
"=>"1411342345879"}
Club Load (0.1ms) SELECT "clubs".* FROM "clubs" WHERE "clubs"."subdomain" = 'test' LIMIT 1
Tour Load (0.3ms) SELECT "tours".* FROM "tours" WHERE (club_id = 2) AND "tours"."id" = ? ORDER BY "tours"."name" ASC LIMIT 1 [["id", 11]]


STACK TRACE:

ArgumentError - wrong number of arguments (1 for 0):
filterrific (1.3.1) lib/filterrific/active_record_extension.rb:52:in block in filterrific_find' filterrific (1.3.1) lib/filterrific/active_record_extension.rb:49:infilterrific_find'
app/controllers/courses_controller.rb:7:in index' actionpack (4.1.4) lib/action_controller/metal/implicit_render.rb:4:insend_action'
actionpack (4.1.4) lib/abstract_controller/base.rb:189:in process_action' actionpack (4.1.4) lib/action_controller/metal/rendering.rb:10:inprocess_action'
actionpack (4.1.4) lib/abstract_controller/callbacks.rb:20:in block in process_action' activesupport (4.1.4) lib/active_support/callbacks.rb:113:incall'
activesupport (4.1.4) lib/active_support/callbacks.rb:229:in block in halting' activesupport (4.1.4) lib/active_support/callbacks.rb:166:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in block in halting' activesupport (4.1.4) lib/active_support/callbacks.rb:229:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in block in halting' activesupport (4.1.4) lib/active_support/callbacks.rb:166:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:299:in block (2 levels) in halting' app/controllers/application_controller.rb:42:inscope_current_club'
activesupport (4.1.4) lib/active_support/callbacks.rb:424:in block in make_lambda' activesupport (4.1.4) lib/active_support/callbacks.rb:298:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:166:in block in halting' activesupport (4.1.4) lib/active_support/callbacks.rb:166:inblock in halting'
activesupport (4.1.4) lib/active_support/callbacks.rb:86:in run_callbacks' actionpack (4.1.4) lib/abstract_controller/callbacks.rb:19:inprocess_action'
actionpack (4.1.4) lib/action_controller/metal/rescue.rb:29:in process_action' actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:31:inblock in process_action'
activesupport (4.1.4) lib/active_support/notifications.rb:159:in block in instrument' activesupport (4.1.4) lib/active_support/notifications/instrumenter.rb:20:ininstrument'
activesupport (4.1.4) lib/active_support/notifications.rb:159:in instrument' actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:30:inprocess_action'
actionpack (4.1.4) lib/action_controller/metal/params_wrapper.rb:250:in process_action' activerecord (4.1.4) lib/active_record/railties/controller_runtime.rb:18:inprocess_action'
actionpack (4.1.4) lib/abstract_controller/base.rb:136:in process' actionview (4.1.4) lib/action_view/rendering.rb:30:inprocess'
actionpack (4.1.4) lib/action_controller/metal.rb:196:in dispatch' actionpack (4.1.4) lib/action_controller/metal/rack_delegation.rb:13:indispatch'
actionpack (4.1.4) lib/action_controller/metal.rb:232:in block in action' actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:indispatch'
actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:50:in call' actionpack (4.1.4) lib/action_dispatch/journey/router.rb:71:inblock in call'
actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in call' actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:678:incall'
dragonfly (1.0.5) lib/dragonfly/middleware.rb:14:in call' rack (1.5.2) lib/rack/etag.rb:23:incall'
rack (1.5.2) lib/rack/conditionalget.rb:25:in call' rack (1.5.2) lib/rack/head.rb:11:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/params_parser.rb:27:in call' actionpack (4.1.4) lib/action_dispatch/middleware/flash.rb:254:incall'
rack (1.5.2) lib/rack/session/abstract/id.rb:225:in context' rack (1.5.2) lib/rack/session/abstract/id.rb:220:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/cookies.rb:560:in call' activerecord (4.1.4) lib/active_record/query_cache.rb:36:incall'
activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:621:in call' activerecord (4.1.4) lib/active_record/migration.rb:380:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:29:in block in call' activesupport (4.1.4) lib/active_support/callbacks.rb:82:inrun_callbacks'
actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:27:in call' actionpack (4.1.4) lib/action_dispatch/middleware/reloader.rb:73:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/remote_ip.rb:76:in call' better_errors (1.1.0) lib/better_errors/middleware.rb:84:inprotected_app_call'
better_errors (1.1.0) lib/better_errors/middleware.rb:79:in better_errors_call' better_errors (1.1.0) lib/better_errors/middleware.rb:56:incall'
actionpack (4.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:17:in call' actionpack (4.1.4) lib/action_dispatch/middleware/show_exceptions.rb:30:incall'
railties (4.1.4) lib/rails/rack/logger.rb:38:in call_app' railties (4.1.4) lib/rails/rack/logger.rb:20:inblock in call'
activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in block in tagged' activesupport (4.1.4) lib/active_support/tagged_logging.rb:26:intagged'
activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in tagged' railties (4.1.4) lib/rails/rack/logger.rb:20:incall'
request_store (1.0.7) lib/request_store/middleware.rb:8:in call' actionpack (4.1.4) lib/action_dispatch/middleware/request_id.rb:21:incall'
rack (1.5.2) lib/rack/methodoverride.rb:21:in call' rack (1.5.2) lib/rack/runtime.rb:17:incall'
activesupport (4.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in call' dragonfly (1.0.5) lib/dragonfly/cookie_monster.rb:9:incall'
rack (1.5.2) lib/rack/lock.rb:17:in call' actionpack (4.1.4) lib/action_dispatch/middleware/static.rb:64:incall'
rack (1.5.2) lib/rack/sendfile.rb:112:in call' railties (4.1.4) lib/rails/engine.rb:514:incall'
railties (4.1.4) lib/rails/application.rb:144:in call' unicorn (4.8.3) lib/unicorn/http_server.rb:576:inprocess_client'
unicorn (4.8.3) lib/unicorn/http_server.rb:670:in worker_loop' unicorn (4.8.3) lib/unicorn/http_server.rb:525:inspawn_missing_workers'
unicorn (4.8.3) lib/unicorn/http_server.rb:140:in start' unicorn (4.8.3) bin/unicorn_rails:209:in<top (required)>'
bin/unicorn_rails:16:in <top (required)>' -e:1:in

'
`

Using Filterrific with Devise gives an undefined method `filterrific' on the User model.

I am trying to use Filterrific with Devise, but getting an undefined method error for filterrific in the user model.

From the debug log it looks like it's coming from the "directive"

class User < ActiveRecord::Base

This directive enables Filterrific for the Student class.

We define a default sorting by most recent sign up, and then

we make a number of filters available through Filterrific.

filterrific(
:default_settings => { :sorted_by => 'created_at_desc' },
:filter_names => [
:sorted_by,
:search_query,
:with_country_id,
:with_created_at_gte
]
)

join 2 or more tables with unique filters

I am not sure if what I want to do is even possible with filterific.
I am currently looking into building a single unified search for my website.
This would hit a few different tables with different types of data.
Ideally what I could do is be able to do is have the scopes for each in the their model and then in the controller for the unified search it would be able to do queries against all of the models based on their relevant options and then combine all of the data.
Then in my view I would just check the type of object it is to determine how it displays in the search.

I am not sure if this is possible with filterific, I can't find any examples of this working anywhere else.

Thanks

Add sort_link?

Im trying to move away from from ransack/meta_search to filterrific. However there is one form helper method I could live without, unfortunately I don't enough time with the source code myself to figure out how to implement it. Im talking the #sort_link method, it basicly allows a user to click on the link and have it sort on the specific named scope.

https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/helpers/form_helper.rb#L38

def sort_link(search, attribute, *args)
  # Extract out a routing proxy for url_for scoping later
  if search.is_a?(Array)
    routing_proxy = search.shift
    search = search.first
  end

  raise TypeError, "First argument must be a Ransack::Search!" unless
    Search === search

  search_params = params[search.context.search_key].presence ||
    {}.with_indifferent_access

  attr_name = attribute.to_s

  name = (
    if args.size > 0 && !args.first.is_a?(Hash)
      args.shift.to_s
    else
      Translate.attribute(attr_name, :context => search.context)
    end
    )

  if existing_sort = search.sorts.detect { |s| s.name == attr_name }
    prev_attr, prev_dir = existing_sort.name, existing_sort.dir
  end

  options = args.first.is_a?(Hash) ? args.shift.dup : {}
  default_order = options.delete :default_order
  current_dir = prev_attr == attr_name ? prev_dir : nil

  if current_dir
    new_dir = current_dir == 'desc' ? 'asc' : 'desc'
  else
    new_dir = default_order || 'asc'
  end

  html_options = args.first.is_a?(Hash) ? args.shift.dup : {}
  css = ['sort_link', current_dir].compact.join(' ')
  html_options[:class] = [css, html_options[:class]].compact.join(' ')
  query_hash = {}
  query_hash[search.context.search_key] = search_params
  .merge(:s => "#{attr_name} #{new_dir}")
  options.merge!(query_hash)
  options_for_url = params.merge options

  url = if routing_proxy && respond_to?(routing_proxy)
    send(routing_proxy).url_for(options_for_url)
  else
    url_for(options_for_url)
  end

  link_to(
    [ERB::Util.h(name), order_indicator_for(current_dir)]
      .compact
      .join(' ')
      .html_safe,
    url,
    html_options
    )
end

undefined method `new' for Filterrific:Module

This is my offers_controller index method:

def index
filterrific_params = {:with_partner_id => current_partner.id}.deep_merge(params[:filterrific] || session[:filterrific_offers] || {})
@filterrific = Filterrific.new(Offer, filterrific_params)
@offers = Offer.filterrific_find(@filterrific).page(params[:page]).per(10).order('created_at' => :desc)
session[:filterrific_offers] = @filterrific.to_hash
respond_to do |format|
format.html
format.js
end
end

This worked perfect untill I updated filterrific-gem to 2.0.5
If I go back to using 1.4.2 for example, I get:

undefined method filterrific_filter_names'`

What exactly am I doing wrong?
Thanks!

undefined method `sorted_by' for #<Student::ActiveRecord_Relation:0x007ff436318418>

I followed the exact setup steps in the example and getting the above error message. Any ideas why this might be happening?

Student.rb

belongs_to :user
has_many :assessments
attr_accessor :referer

filterrific(
default_filter_params: { sorted_by: 'created_at_desc' },
available_filters: [
  :sorted_by,
  :search_query,
  :with_created_at_gte
]
  )

Student controller:

  @patients = current_user.patients.sort_by &:first_name

  @filterrific = initialize_filterrific(
    Patient,
    params[:filterrific]
  ) or return
   @patients = @filterrific.find.page(params[:page])

  respond_to do |format|
    format.html
    format.js
  end
end

Is there a way to get the current_user into one of the Filterrific scopes?

I have a list of Stories I am displaying. I have added a checkbox to the list filters. When the checkbox is checked, I want to only display the Stories that the current user likes. The checkbox will only pass whether it is checked or not. The controller knows the current_user but the model, where the scopes are defined, does not. Is there a way to add it into the @filterrific object from the controller so the scope has access to the current_user? Is there an easier way to do this that I am just missing? I'm still kind of new to Rails. Thanks!

Disable Auto-populate at page load?

Hi there - love your gem! I would like to use it with a db with about 100k entires, however I would like for all those entries to not auto-populate as soon as the index.html.erb page is loaded; only after a user has entered their search/sort criteria, and if the filters are reset the results would again clear.

I've tried playing with the controller code in an attempt to prevent @inst_var = @filterrific.find.page(params[:page]) from populating right away, but have only succeeded in breaking the code over and again. Any advice is welcomed. Thanks!

undefined method `options_for_select'

I'm new in the use of filterrific.
In my application I got the error in the subject.
I'm using
filterrific (2.0.5)
rails (4.2.1)
ruby 1.9.3 p545 on win7

STACK TRACE:

activerecord (4.2.1) lib/active_record/dynamic_matchers.rb:26:in method_missing' app/controllers/prevheads_controller.rb:9:inindex'
actionpack (4.2.1) lib/action_controller/metal/implicit_render.rb:4:in send_action' actionpack (4.2.1) lib/abstract_controller/base.rb:198:inprocess_action'
actionpack (4.2.1) lib/action_controller/metal/rendering.rb:10:in process_action' actionpack (4.2.1) lib/abstract_controller/callbacks.rb:20:inblock in process_action'
activesupport (4.2.1) lib/active_support/callbacks.rb:117:in call' activesupport (4.2.1) lib/active_support/callbacks.rb:117:incall'
activesupport (4.2.1) lib/active_support/callbacks.rb:555:in block (2 levels) in compile' activesupport (4.2.1) lib/active_support/callbacks.rb:505:incall'
activesupport (4.2.1) lib/active_support/callbacks.rb:505:in call' activesupport (4.2.1) lib/active_support/callbacks.rb:92:in_run_callbacks'
activesupport (4.2.1) lib/active_support/callbacks.rb:776:in _run_process_action_callbacks' activesupport (4.2.1) lib/active_support/callbacks.rb:81:inrun_callbacks'
actionpack (4.2.1) lib/abstract_controller/callbacks.rb:19:in process_action' actionpack (4.2.1) lib/action_controller/metal/rescue.rb:29:inprocess_action'
actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:32:in block in process_action' activesupport (4.2.1) lib/active_support/notifications.rb:164:inblock in instrument'
activesupport (4.2.1) lib/active_support/notifications/instrumenter.rb:20:in instrument' activesupport (4.2.1) lib/active_support/notifications.rb:164:ininstrument'
actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:30:in process_action' actionpack (4.2.1) lib/action_controller/metal/params_wrapper.rb:250:inprocess_action'
activerecord (4.2.1) lib/active_record/railties/controller_runtime.rb:18:in process_action' actionpack (4.2.1) lib/abstract_controller/base.rb:137:inprocess'
actionview (4.2.1) lib/action_view/rendering.rb:30:in process' actionpack (4.2.1) lib/action_controller/metal.rb:196:indispatch'
actionpack (4.2.1) lib/action_controller/metal/rack_delegation.rb:13:in dispatch' actionpack (4.2.1) lib/action_controller/metal.rb:237:inblock in action'
actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:74:in call' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:74:indispatch'
actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:43:in serve' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:43:inblock in serve'
actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in each' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:inserve'
actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:819:in call' rack (1.6.1) lib/rack/etag.rb:24:incall'
rack (1.6.1) lib/rack/conditionalget.rb:25:in call' rack (1.6.1) lib/rack/head.rb:13:incall'
actionpack (4.2.1) lib/action_dispatch/middleware/params_parser.rb:27:in call' actionpack (4.2.1) lib/action_dispatch/middleware/flash.rb:260:incall'
rack (1.6.1) lib/rack/session/abstract/id.rb:225:in context' rack (1.6.1) lib/rack/session/abstract/id.rb:220:incall'
actionpack (4.2.1) lib/action_dispatch/middleware/cookies.rb:560:in call' activerecord (4.2.1) lib/active_record/query_cache.rb:36:incall'
activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:649:in call' activerecord (4.2.1) lib/active_record/migration.rb:378:incall'
actionpack (4.2.1) lib/action_dispatch/middleware/callbacks.rb:29:in block in call' activesupport (4.2.1) lib/active_support/callbacks.rb:88:incall'
activesupport (4.2.1) lib/active_support/callbacks.rb:88:in _run_callbacks' activesupport (4.2.1) lib/active_support/callbacks.rb:776:in_run_call_callbacks'
activesupport (4.2.1) lib/active_support/callbacks.rb:81:in run_callbacks' actionpack (4.2.1) lib/action_dispatch/middleware/callbacks.rb:27:incall'
actionpack (4.2.1) lib/action_dispatch/middleware/reloader.rb:73:in call' actionpack (4.2.1) lib/action_dispatch/middleware/remote_ip.rb:78:incall'
actionpack (4.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:17:in call' web-console (2.1.2) lib/web_console/middleware.rb:37:incall'
actionpack (4.2.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in call' railties (4.2.1) lib/rails/rack/logger.rb:38:incall_app'
railties (4.2.1) lib/rails/rack/logger.rb:20:in block in call' activesupport (4.2.1) lib/active_support/tagged_logging.rb:68:inblock in tagged'
activesupport (4.2.1) lib/active_support/tagged_logging.rb:26:in tagged' activesupport (4.2.1) lib/active_support/tagged_logging.rb:68:intagged'
railties (4.2.1) lib/rails/rack/logger.rb:20:in call' actionpack (4.2.1) lib/action_dispatch/middleware/request_id.rb:21:incall'
rack (1.6.1) lib/rack/methodoverride.rb:22:in call' rack (1.6.1) lib/rack/runtime.rb:18:incall'
activesupport (4.2.1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in call' rack (1.6.1) lib/rack/lock.rb:17:incall'
actionpack (4.2.1) lib/action_dispatch/middleware/static.rb:113:in call' rack (1.6.1) lib/rack/sendfile.rb:113:incall'
railties (4.2.1) lib/rails/engine.rb:518:in call' railties (4.2.1) lib/rails/application.rb:164:incall'
rack (1.6.1) lib/rack/lock.rb:17:in call' rack (1.6.1) lib/rack/content_length.rb:15:incall'
rack (1.6.1) lib/rack/handler/webrick.rb:89:in service' C:/Ruby193/lib/ruby/1.9.1/webrick/httpserver.rb:138:inservice'
C:/Ruby193/lib/ruby/1.9.1/webrick/httpserver.rb:94:in run' C:/Ruby193/lib/ruby/1.9.1/webrick/server.rb:191:inblock in start_thread'
Request

Parameters:

None
Toggle session dump
Toggle env dump
Response

Headers:

None

MODEL:

class Prevhead < ActiveRecord::Base

belongs_to :client
belongs_to :carto
belongs_to :costoli
belongs_to :onda
belongs_to :fusto
belongs_to :inco
belongs_to :confe
belongs_to :resa
belongs_to :costoli2

filterrific(
available_filters: [
:with_client_id,
:with_articolo
]
)

scope :with_client_id, lambda { |client_ids|
where(client_id: [*client_ids])
}
scope :with_articolo, lambda { order('articolo ASC') }

validates :client_id, :inclusion => {:in => 2..1000, :message => "Cliente non selezionato"}
validates :articolo, presence: {message: "Articolo non definito"}
validates :descrizione, presence: {message: "Descrizione non inserita"}

validates_numericality_of :qta, message: "Quantita non definita", on: :create
validates_numericality_of :qta, message: "Quantita non definita", on: :edit

validates_numericality_of :scarto, message: "Scarto non definito", on: :create
validates_numericality_of :scarto, message: "Scarto non definito", on: :edit

validates_numericality_of :dim1, message: "Altezza non definita", on: :create
validates_numericality_of :dim1, message: "Altezza non definita", on: :edit

validates_numericality_of :dim2, message: "Larghezza non definita", on: :create
validates_numericality_of :dim2, message: "Larghezza non definita", on: :edit

validates :carto_id, :inclusion => {:in => 2..1000, :message => "Cartoncino non selezionato"}
validates :resa_id, :inclusion => {:in => 2..1000, :message => "Resa non selezionata"}
validates :costoli_id, :inclusion => {:in => 2..1000, :message => "Linea non selezionata"}
end

CONTROLLER:

class PrevheadsController < ApplicationController
def index
@filterrific = initialize_filterrific(
Prevhead,
params[:filterrific],
select_options: {
with_client_id: Client.options_for_select,
},
persistence_id: 'shared_key',
default_filter_params: {},
available_filters: [],
) or return
@prevheads = @filterrific.find.paginate(:page => params[:page], :per_page => 12).order("num DESC","vers DESC").joins(:client)

respond_to do |format|
  format.html
  format.js
end

end

def show
@prevhead = Prevhead.find(params[:id])
end

def new
@prevhead = Prevhead.new
end

def edit
@prevhead = Prevhead.joins(:client, :carto, :costoli, :fusto, :inco, :confe, :resa).find(params[:id])
end

private
def prevhead_params
params.require(:prevhead).permit(:num, :vers, :client_id, :qta, :articolo, :descrizione, :qta, :scarto, :dim1, :dim2, :formatoc, :carto_id, :resa_id, :costoli_id, :costoli2_id, :onda_id, :fusto_id, :inco_id, :confe_id, :traspo, :data_elab, :co_carto, :co_stampa, :co_avvsta, :co_stampa2, :co_avvsta2, :co_onda, :co_fusto, :co_avvfust, :co_inco, :co_avvinco, :co_confe, :preventivo, :prevtraspo, :un_peso, :un_costo, :un_stampa, :un_stampa2, :un_coston, :un_costof, :un_costoi, :un_sovrap, :un_confe, :un_contenuto, :note, :desclinea2, :descform2, :descolor2, :descdiff2)
end

end

INDEX.HTML.ERB

<%= notice %>

<%= form_for_filterrific @filterrific do |f| %>

Cliente <%= f.select( :with_client_id, @filterrific.select_options[:with_client_id] ) %>
Articolo <%# give the search field the 'filterrific-periodically-observed' class for live updates %> <%= f.text_field( :prod, class: 'filterrific-periodically-observed' ) %>
<%= link_to( 'Reset filters', reset_filterrific_url, ) %>
<%# add an automated spinner to your form when the list is refreshed %> <%= render_filterrific_spinner %> <% end %>

<%= render(
partial: 'zzz/elenco',
locals: { prevheads: @prevheads}
) %>


PARTIAL zzz/_elenco

<%= notice %>

<% @page_title="Preventivi" %>

<% @prevheads.each do |prevhead| %>
    <td><%= button_to 'Mostra', prevhead_path(prevhead), method: :show %></td>
    <td><%= button_to 'Copia', copia_path(prevhead), method: :copia %></td>
    <td><%= link_to 'Stampa', stampa_path(prevhead), method: :stampa, target: :_blank %></td>

  </tr>
<% end %>
Numero
Versione
Cliente
Articolo
Descrizione
Quantità
Preventivo
Unitario
Trasporto
Unit Tot
Data
<%= prevhead.num %> <%= prevhead.vers %> <%= prevhead.client.ragsoc %> <%= prevhead.articolo %> <%= prevhead.descrizione %> <%= number_with_auto_precision(prevhead.qta, :separator => ',', :delimiter => '.') %> <%= number_to_currency(prevhead.preventivo, :unit=>'€') %> <%= number_to_currency(prevhead.preventivo/prevhead.qta, :unit=>'€', :precision =>3) %> <%= number_to_currency(prevhead.traspo, :unit=>'€') %> <%= number_to_currency(prevhead.prevtraspo/prevhead.qta, :unit=>'€', :precision =>3) %> <%= prevhead.data_elab %>

<%= will_paginate @prevheads %>


TABLE prevheads

create_table "prevheads", force: :cascade do |t|
t.integer "num", limit: 4, null: false
t.integer "vers", limit: 4, null: false
t.integer "client_id", limit: 4, null: false
t.string "articolo", limit: 100, null: false
t.string "descrizione", limit: 200, null: false
t.decimal "qta", precision: 10, scale: 2, null: false
t.decimal "scarto", precision: 10, scale: 3, null: false
t.decimal "dim1", precision: 10, scale: 3, null: false
t.decimal "dim2", precision: 10, scale: 3, null: false
t.string "formatoc", limit: 100, null: false
t.integer "carto_id", limit: 4, null: false
t.integer "resa_id", limit: 4, null: false
t.integer "costoli_id", limit: 4, null: false
t.integer "costoli2_id", limit: 4, null: false
t.integer "onda_id", limit: 4, default: 1, null: false
t.integer "fusto_id", limit: 4, default: 1, null: false
t.integer "inco_id", limit: 4, default: 1, null: false
t.integer "confe_id", limit: 4, default: 1, null: false
t.decimal "traspo", precision: 10, scale: 3, default: 0.0, null: false
t.date "data_elab"
t.decimal "co_carto", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "co_stampa", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "co_avvsta", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "co_stampa2", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "co_avvsta2", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "co_onda", precision: 10, scale: 3, default: 0.0
t.decimal "co_fusto", precision: 10, scale: 3, default: 0.0
t.decimal "co_avvfust", precision: 10, scale: 3, default: 0.0
t.decimal "co_inco", precision: 10, scale: 3, default: 0.0
t.decimal "co_avvinco", precision: 10, scale: 3, default: 0.0
t.decimal "co_confe", precision: 10, scale: 3, default: 0.0
t.decimal "preventivo", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "prevtraspo", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "un_peso", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "un_costo", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "un_stampa", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "un_stampa2", precision: 10, scale: 3, default: 0.0, null: false
t.decimal "un_coston", precision: 10, scale: 3, default: 0.0
t.decimal "un_costof", precision: 10, scale: 3, default: 0.0
t.decimal "un_costoi", precision: 10, scale: 3, default: 0.0
t.decimal "un_sovrap", precision: 10, scale: 3, default: 0.0
t.decimal "un_confe", precision: 10, scale: 3, default: 0.0
t.decimal "un_contenuto", precision: 10, scale: 3, default: 0.0
t.string "note", limit: 255
t.string "desclinea2", limit: 50
t.string "descform2", limit: 50
t.string "descolor2", limit: 50
t.string "descdiff2", limit: 50
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

Thank you for any suggestions ...

Should we cast negative number as int?

Kind of linked to the following issue #34

When the params hash is conditioned in ParamSet, the string that "looks like" a negative number are not casted into negative int.

ex:

[1] > condition_filterrific_params { 'filter_negative_int' => '-42' }
=> { 'filter_negative_int' => '-42' }
# shouldn't this be { 'filter_negative_int' => -42 } ?

Does it make sense to cast as a negative int?

Sort Scope

Hi, I have two questions about the gem. First question is, i have a model Post and a model Comment. Post stands in a has_many relationship to Comment. Post should order by count of Comment. I would not use counter cache for this. How should my scope be?
The second question is, i have for my Post model a twitter counter method for count the Tweets. Usually I was to do it like:

Posts.sort_by{ |x| x.twitter_counter }
But unfortunately it does not work, so since it is an array. How can i solve this with a scope ?

Thanks

scope with multiple arguments

My issue is fairly simple, in my app I have this scope that retrieves all the courses within a certain distance with the help of a postgis database:
scope :with_distance, -> (lat, lng, distance_in_meters) {...}
The scope is working but I don't know how to write the select options for a scope that has more than one argument. I wrote this huge mess that's not even working (wrong number of arguments) but you get the idea:
[ [['2 km'], [current_user.lat, current_user.lng, 2000]], [['5 km'], [current_user.lat, current_user.lng, 5000]] ]
I've been trying to solve this for a long time, any suggestion would be greatly appreciated

Cascading Dropdowns for Filterrific

How do I do cascading dropdown in Filterrific
give that i have Domain -> Sector -> Subsector
I tried to initialize the select_options for Sector and Subsector to an empty set and then provide it with value once Domain has been selected.

However in my model when I try to access
filterrific :select_options => { :with_sector_id => Sector.options_for_select }
I get an error "wrong number of arguments (0 for 1)"

See example below.

class Profile < ActiveRecord::Base
filterrific :default_filter_params => { :sorted_by => 'created_at_desc' },
:available_filters => %w[
with_domain_id
with_sector_id
with_subsector_id
]
scope :with_domain_id, lambda { |with_domain_id|
# select and search for the content.
profile_expertises = Expertise.arel_table
profile_searches = Profile.arel_table

where(
    Expertise \
      .where(profile_expertises[:profile_id].eq(profile_searches[:id] )) \
      .where(profile_expertises[:domain_id].in([*with_domain_id].map(&:to_i))) \
      .exists
)
filterrific :select_options => { :with_sector_id =>  Sector.options_for_select }

class SearchesController < ApplicationController

GET /profiles

GET /profiles.json

def index
@filterrific = initialize_filterrific(
Profile,
params[:filterrific],
:select_options => {
sorted_by: Profile.options_for_sorted_by,
with_domain_id: Domain.options_for_select,
with_sector_id: [],
with_subsector_id: [],
}
)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.