usefull_filter 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +4 -0
- data/Gemfile +19 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +32 -0
- data/app/helpers/usefull_filter_helper.rb +72 -0
- data/lib/generators/usefull_filter/install/install_generator.rb +17 -0
- data/lib/usefull_filter.rb +7 -0
- data/lib/usefull_filter/engine.rb +20 -0
- data/lib/usefull_filter/exceptions.rb +17 -0
- data/lib/usefull_filter/filter_form_builder.rb +183 -0
- data/lib/usefull_filter/version.rb +4 -0
- metadata +106 -0
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#You can add lacal gems with
|
2
|
+
# gem "my_gem", :path => "/home/www/gems/my_gem"
|
3
|
+
#you must remove the path in production or if you change server and replace with:
|
4
|
+
# git "git@10.2.252.240:my_gem.git"
|
5
|
+
|
6
|
+
source "http://rubygems.org"
|
7
|
+
|
8
|
+
gem "rails", "~>3.0.14"
|
9
|
+
gem "meta_search"
|
10
|
+
|
11
|
+
group :development, :test do
|
12
|
+
gem "ruby-debug"
|
13
|
+
gem "capybara", ">= 0.4.0"
|
14
|
+
gem "sqlite3"
|
15
|
+
gem "single_test"
|
16
|
+
end
|
17
|
+
|
18
|
+
gemspec
|
19
|
+
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
require "bundler/gem_tasks"
|
6
|
+
rescue LoadError
|
7
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rake'
|
11
|
+
require 'rake/testtask'
|
12
|
+
require 'rdoc/task'
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
Rake::TestTask.new(:test) do |t|
|
17
|
+
t.libs << 'lib'
|
18
|
+
t.libs << 'test'
|
19
|
+
t.pattern = 'test/**/*_test.rb'
|
20
|
+
t.verbose = false
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default => :test
|
24
|
+
|
25
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
26
|
+
rdoc.rdoc_dir = 'rdoc'
|
27
|
+
rdoc.title = 'usefull_filter'
|
28
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
29
|
+
rdoc.rdoc_files.include('README.rdoc')
|
30
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#require "usefull_filter/filter_form_builder"
|
2
|
+
#L'helper si occupa di wrappare la classe MetaSearch permettendo l'utilizzo di Filtri selezionabili dall'utente
|
3
|
+
#
|
4
|
+
#[documents_controller]
|
5
|
+
# Vedi TableHelper
|
6
|
+
#
|
7
|
+
#[index.html.erb]
|
8
|
+
# <%=filter_for_new @search, :url => magazzino_documents_path do |f| %>
|
9
|
+
# <%= f.text_field :data, :size => 10, :filters => ["equals", "less_than_or_equal_to", "greater_than_or_equal_to"] %>
|
10
|
+
# <%= f.text_field :DoCNr, :filters_type => :number %>
|
11
|
+
# <%= f.text_field :TbDoC, :filters_only => ["equals"] %>
|
12
|
+
# <%= f.text_field :BollaXENrDoC, filters_except => ["equals", "does_not_equal"] %>
|
13
|
+
# <%= f.text_field :DoCSit %>
|
14
|
+
# <%= f.submit %>
|
15
|
+
# <% end %>
|
16
|
+
module UsefullFilterHelper
|
17
|
+
#Contatta l'url passato ripassando i filtri attivi in @search
|
18
|
+
def filter_button_tag(name, url, method = :get)
|
19
|
+
if @search.kind_of?(MetaSearch::Builder)
|
20
|
+
form_tag(url, :method => method) do
|
21
|
+
@search.search_attributes.each do |k,v|
|
22
|
+
if v.kind_of?(Array)
|
23
|
+
v.each{|vv| concat hidden_field_tag("search[#{k}][]", vv)}
|
24
|
+
else
|
25
|
+
concat hidden_field_tag("search[#{k}]", v)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
concat submit_tag(name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def filter_for_new(obj, *args, &proc)
|
34
|
+
filter_for(obj, *args, &proc)
|
35
|
+
end
|
36
|
+
|
37
|
+
#Cerca una serie di filtri utilizzando MetaSearch di cui fa il wrapper
|
38
|
+
#obj è una istanza metashearch
|
39
|
+
def filter_for(obj, *args, &proc)
|
40
|
+
unless obj.blank?
|
41
|
+
options = args.extract_options!
|
42
|
+
|
43
|
+
options[:html] ||= {}
|
44
|
+
options[:html][:select] ||= {}
|
45
|
+
options[:html][:input] ||= {}
|
46
|
+
options[:html][:method] ||= :get
|
47
|
+
options[:html][:class] ||= "usefull_filter_container"
|
48
|
+
options[:html_1] = options.delete(:html)
|
49
|
+
options.merge!(:builder => UsefullFilter::FilterFormBuilder)
|
50
|
+
|
51
|
+
remove_filter_label = I18n.t("remove_filter", :scope => "meta_search.buttons")
|
52
|
+
filter_title = I18n.t("filter_title", :scope => "meta_search.buttons")
|
53
|
+
|
54
|
+
#Estraggo le options che mi interessano, perchè una volta passate al builder
|
55
|
+
#per qulache arcano motivo vengono alterate....
|
56
|
+
classe = options[:html_1].delete(:class)
|
57
|
+
url = options[:url]
|
58
|
+
#UserSession.log("FilterHelper#filter_for_new: options=#{options.inspect}")
|
59
|
+
content_tag(:div,
|
60
|
+
content_tag(:h3, filter_title) +
|
61
|
+
content_tag(:ul,
|
62
|
+
form_for(obj, *(args << options), &proc) +
|
63
|
+
form_tag(url_for(url), :method => :get) do
|
64
|
+
obj.search_attributes.each_key {|k| concat hidden_field_tag("search[#{k}]") }
|
65
|
+
concat submit_tag(remove_filter_label, :class => "usefull_filter_push-2")
|
66
|
+
end ),
|
67
|
+
:class => classe)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module UsefullFilter
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
desc "Install generator for UsefullFilter gem"
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
6
|
+
|
7
|
+
#def copy_config
|
8
|
+
# directory "config"
|
9
|
+
#end
|
10
|
+
|
11
|
+
#def copy_public
|
12
|
+
# directory "public"
|
13
|
+
#end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module UsefullFilter
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
|
4
|
+
config.autoload_paths += Dir["#{config.root}/lib/**/"]
|
5
|
+
|
6
|
+
initializer 'usefull_filter.helper' do |app|
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
include UsefullFilterHelper
|
9
|
+
end
|
10
|
+
ActiveSupport.on_load(:action_view) do
|
11
|
+
include UsefullFilterHelper
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
#Add ere require to specific file or gem used
|
20
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#Localize messages in it.CustomError.MyError
|
2
|
+
module UsefullFilter
|
3
|
+
class CustomError < StandardError
|
4
|
+
def initialize(*args)
|
5
|
+
@options = args.extract_options!
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def message
|
10
|
+
@options.merge!({:default => "Error : #{@options.inspect}"})
|
11
|
+
I18n.t("#{self.class.name.gsub(/::/,'.')}", @options )
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
#class MyError < CustomError; end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,183 @@
|
|
1
|
+
module UsefullFilter
|
2
|
+
class FilterFormBuilder < ActionView::Helpers::FormBuilder
|
3
|
+
|
4
|
+
DEFAULT_TYPES=["equals", "does_not_equal", "in", "not_in"]
|
5
|
+
STRING_TYPES=["contains", "does_not_contain", "starts_with", "does_not_start_with", "ends_with", "does_not_end_with"]
|
6
|
+
NUMBER_TYPES=["greater_than", "greater_than_or_equal_to", "less_than", "less_than_or_equal_to"]
|
7
|
+
BOOLEAN_TYPES=["is_true", "is_false"]
|
8
|
+
OTHER_TYPES=["is_present", "is_blank"]
|
9
|
+
|
10
|
+
#Ridefinisco il metodo per wrapparlo all'interno di una lista
|
11
|
+
#Accetta i seguenti parametri:
|
12
|
+
#* :default_filter => "equals"
|
13
|
+
#* :filters => ["equals", ....]
|
14
|
+
#
|
15
|
+
#Il nome sarà del tipo
|
16
|
+
#* :ART
|
17
|
+
#* "document.activity.id" (come per la tabelle)
|
18
|
+
def text_field(object_name, *args)
|
19
|
+
opt = define_args(args, object_name)
|
20
|
+
name = object_name.to_s.gsub(/\./, "_")
|
21
|
+
opt.merge!(@options[:html_1][:input])
|
22
|
+
#UserSession.log("FilterHelper#text_field:opt=#{opt.inspect}")
|
23
|
+
@template.content_tag(:li) do
|
24
|
+
@template.concat filter_list(name, opt[:default_filter], opt)
|
25
|
+
@template.concat " "
|
26
|
+
@template.concat super(default(name, opt[:default_filter]), opt)
|
27
|
+
##UserSession.log("FilterHelper#text_field:object_name=#{object_name.inspect}")
|
28
|
+
#@template.concat attribute_type(object_name) == :Date ? @template.link_to(@template.image_tag('calendar16.png'), '#', :onclick => "show_calendar('search_data_prevista_equals')") : ''
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#Utilizza come filtro una combo, con i valori passati nell'array
|
33
|
+
def select(object_name, array, *args)
|
34
|
+
opt = define_args(args, object_name)
|
35
|
+
name = object_name.to_s.gsub(/\./, "_")
|
36
|
+
opt.merge!(@options[:html_1][:input])
|
37
|
+
@template.content_tag(:li) do
|
38
|
+
@template.concat filter_list(name, opt[:default_filter], opt)
|
39
|
+
@template.concat " "
|
40
|
+
#@template.concat select("search", default(name, opt[:default_filter]), array.collect {|p| [p,p]}, opt)
|
41
|
+
@template.concat super(default(name, opt[:default_filter]), array, opt)
|
42
|
+
##UserSession.log("FilterHelper#text_field:object_name=#{object_name.inspect}")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#Utilizza come filtro un elenco di valori rappresentati da una check_box
|
47
|
+
#che vengono gestiti come OR
|
48
|
+
#def checks(object_name, array, *args, &block)
|
49
|
+
# super.to_s.html_safe
|
50
|
+
#end
|
51
|
+
|
52
|
+
|
53
|
+
#Genera una doppia text_box per gestire i filtri tra due
|
54
|
+
def between_field(object_name, *args)
|
55
|
+
opt = define_args(args, object_name)
|
56
|
+
name = object_name.to_s.gsub(/\./, "_")
|
57
|
+
@template.content_tag(:li,
|
58
|
+
multiparameter_field(name.to_s + "_between",
|
59
|
+
{:field_type => :text_field}, {:field_type => :text_field}, :size => 5))
|
60
|
+
end
|
61
|
+
|
62
|
+
def submit
|
63
|
+
applay_filter_label = I18n.t(:applay_filter, :scope => "meta_search.buttons")
|
64
|
+
super(applay_filter_label, :class => "usefull_filter_push-1")
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
#Aggiusta il vettore dei parametri passati
|
70
|
+
#* :default_filter => "equals" filtro di default che deve essere presente in tutti i metodi
|
71
|
+
#* :filters_only => ["equals", .. ] elenco di filtri da utilizzare, rimpiazza anche i dafault
|
72
|
+
#* :filters_except => ["equals", .. ] elenco di filtri da escludere
|
73
|
+
#* :filters => [..] elenco dei filtri richiesti, sovrascrive i default
|
74
|
+
#* :filters_type => :string | :number | :boolean | :other da aggiungere a quelli gia presenti
|
75
|
+
def define_args(args, object_name)
|
76
|
+
opt = args.extract_options!
|
77
|
+
#Il filtro di default e _equals che deve essere presente su tutti i campi
|
78
|
+
opt[:filters] ||= DEFAULT_TYPES + type(object_name)
|
79
|
+
opt[:default_filter] ||= opt[:filters].include?("equals") ? "equals" : opt[:filters].first
|
80
|
+
opt[:filters_only] ||= []
|
81
|
+
opt[:filters_except] ||= []
|
82
|
+
case opt[:filters_type]
|
83
|
+
when :string
|
84
|
+
opt[:filters] |= STRING_TYPES
|
85
|
+
when :number
|
86
|
+
opt[:filters] |= NUMBER_TYPES
|
87
|
+
when :boolean
|
88
|
+
opt[:filters] |= BOOLEAN_TYPES
|
89
|
+
when :other
|
90
|
+
opt[:filters] |= OTHER_TYPES
|
91
|
+
end
|
92
|
+
|
93
|
+
opt[:filters] -= opt[:filters_except]
|
94
|
+
opt[:filters] = opt[:filters_only] unless opt[:filters_only] .blank?
|
95
|
+
opt
|
96
|
+
end
|
97
|
+
|
98
|
+
#Costruisce l'elenco dei filtri da utilizzare
|
99
|
+
#seleziona come selected il parametro trovato in params[] per garantire coerenza dopo il reload
|
100
|
+
def options_list(object_name, args, default_filter="equals")
|
101
|
+
filters = args[:filters].dup
|
102
|
+
filters.map! {|o|
|
103
|
+
"<option value = '" + object_name.to_s + "_" + o + "'" +
|
104
|
+
(default(object_name,default_filter) == object_name.to_s + "_" + o ? " selected = 'selected'" : "") +
|
105
|
+
" >" +
|
106
|
+
I18n.t(o, :scope =>"meta_search.predicates", :attribute => human(object_name)) +
|
107
|
+
"</option>"}
|
108
|
+
filters.join("").html_safe
|
109
|
+
end
|
110
|
+
|
111
|
+
#Crea una lista dei filtri disponibili per il campo
|
112
|
+
def filter_list(object_name, default_filter, args)
|
113
|
+
list = options_list(object_name, args,default_filter)
|
114
|
+
##UserSession.log("FilterHelper#filter_list:options=#{@options.inspect}")
|
115
|
+
#UserSession.log("FilterFormBuilder#filter_list list=#{list}")
|
116
|
+
#@template.select_tag(object_name, list.html_safe, :onchange => "document.getElementById('search_' + #{object_name.to_s}).name = 'search[' + this + ']'")
|
117
|
+
@options[:html_1][:select][:onchange] = "$(#{'search_' + default(object_name,default_filter)}).name = 'search[' + this.value + ']'; $(#{'search_' + default(object_name, default_filter)}).id = 'search_' + this.value "
|
118
|
+
@options[:html_1][:select][:id] = object_name.to_s
|
119
|
+
@options[:html_1][:select][:class] = "select_dati"
|
120
|
+
##UserSession.log("FilterHelper#filter_list:options(before select_tag)=#{@options.inspect}")
|
121
|
+
@template.select_tag("", list, @options[:html_1][:select])
|
122
|
+
end
|
123
|
+
|
124
|
+
#Restituisce l'elenco dei filtri associati al tipo di dati del DB
|
125
|
+
def type(object_name)
|
126
|
+
#case @object.base.columns_hash[object_name.to_s].type
|
127
|
+
case attribute_type(object_name)
|
128
|
+
when :String then
|
129
|
+
STRING_TYPES
|
130
|
+
when :Bignum, :Fixnum, :Float, :Date, :Time, :Datetime then
|
131
|
+
NUMBER_TYPES
|
132
|
+
when :TrueClass, :FalseClass then
|
133
|
+
BOOLEAN_TYPES
|
134
|
+
when nil
|
135
|
+
[]
|
136
|
+
else
|
137
|
+
OTHER_TYPES
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
#Restituisce il tipo dellìattributo
|
142
|
+
#gestendo i multilivello document.activity.data_prevista => :Date
|
143
|
+
#==Nota:
|
144
|
+
#* non testata con le relazioni polimorfiche...
|
145
|
+
#* con metodi definit all'utente, restiuisce nil
|
146
|
+
def attribute_type(attribute_name)
|
147
|
+
#UserSession.log("FilterFormBuilder#attribute_type attribute_name=#{attribute_name}, base=#{@object.base.name}")
|
148
|
+
#Aggiungo self. daventi in quanto i campi tipo ART vengono confusi per costanti se non specifico il contesto. SIGH!
|
149
|
+
|
150
|
+
attributes = attribute_name.to_s.split(".")
|
151
|
+
base = @object.base
|
152
|
+
method = attributes.pop
|
153
|
+
#UserSession.log("FilterFormBuilder#attribute_type(1) method=#{method}, base=#{base.name}, attributes=#{attributes.inspect}")
|
154
|
+
if attributes.length > 0
|
155
|
+
attributes.each do |association|
|
156
|
+
reflection = base.reflect_on_association(association.to_sym)
|
157
|
+
base = reflection.blank? ? nil : reflection.klass
|
158
|
+
end
|
159
|
+
end
|
160
|
+
##UserSession.log("FilterFormBuilder#attribute_type(2) method=#{method}")
|
161
|
+
base.columns_hash[method.to_s].klass.name.to_sym unless base.blank? || base.columns_hash[method.to_s].blank?
|
162
|
+
end
|
163
|
+
|
164
|
+
#Restituisce il nome del campo preso da ActiveRecord
|
165
|
+
def human(object_name)
|
166
|
+
##UserSession.log("FilterFormBuilder#human classe=#{@object.class.name}")
|
167
|
+
@object.base.human_attribute_name(object_name.to_s)
|
168
|
+
end
|
169
|
+
|
170
|
+
#Restituisce il valore di default prelevato da params[]
|
171
|
+
#altrimenti restituisce nome_equals
|
172
|
+
def default(nome, filter="equals")
|
173
|
+
out = ""
|
174
|
+
@object.search_attributes.each_key do |k|
|
175
|
+
out = k unless k.match(/^#{nome.to_s}/).nil?
|
176
|
+
end
|
177
|
+
out = out.blank? ? nome.to_s + "_" + filter : out
|
178
|
+
out
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: usefull_filter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Andrea Bignozzi
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-07-13 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
hash: 27
|
27
|
+
segments:
|
28
|
+
- 3
|
29
|
+
- 0
|
30
|
+
- 14
|
31
|
+
version: 3.0.14
|
32
|
+
type: :runtime
|
33
|
+
requirement: *id001
|
34
|
+
prerelease: false
|
35
|
+
name: rails
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
requirement: *id002
|
48
|
+
prerelease: false
|
49
|
+
name: meta_search
|
50
|
+
description: Wraps meta_search with usefull helpers
|
51
|
+
email:
|
52
|
+
- skylord73@gmail.com
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- app/helpers/usefull_filter_helper.rb
|
61
|
+
- lib/usefull_filter/engine.rb
|
62
|
+
- lib/usefull_filter/filter_form_builder.rb
|
63
|
+
- lib/usefull_filter/exceptions.rb
|
64
|
+
- lib/usefull_filter/version.rb
|
65
|
+
- lib/generators/usefull_filter/install/install_generator.rb
|
66
|
+
- lib/usefull_filter.rb
|
67
|
+
- MIT-LICENSE
|
68
|
+
- Rakefile
|
69
|
+
- Gemfile
|
70
|
+
- README.rdoc
|
71
|
+
- CHANGELOG.md
|
72
|
+
homepage:
|
73
|
+
licenses: []
|
74
|
+
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 3
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
version: "0"
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.24
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Wraps meta_search with usefull helpers
|
105
|
+
test_files: []
|
106
|
+
|