facet_for 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in facet_for.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/facet_for.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "facet_for/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "facet_for"
7
+ s.version = FacetFor::VERSION
8
+ s.authors = ["Jonathan Barket"]
9
+ s.email = ["jbarket@sleepunit.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Provides helpers for creating search forms with Ransack}
12
+ s.description = %q{Provides helpers for creating search forms with Ransack}
13
+
14
+ s.rubyforge_project = "facet_for"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ s.add_runtime_dependency "ransack"
24
+ end
@@ -0,0 +1,3 @@
1
+ module FacetFor
2
+ VERSION = "0.0.1"
3
+ end
data/lib/facet_for.rb ADDED
@@ -0,0 +1,176 @@
1
+ require "facet_for/version"
2
+
3
+ class ActionView::Helpers::FormBuilder
4
+ include ActionView::Helpers::TagHelper
5
+ include ActionView::Helpers::FormTagHelper
6
+ include ActionView::Helpers::FormOptionsHelper
7
+ include ActionView::Helpers::CaptureHelper
8
+ include ActionView::Helpers::AssetTagHelper
9
+
10
+ def facet_for(column, *args)
11
+ options = args.extract_options!
12
+
13
+ facet_html = ''
14
+
15
+ # Here, we collect information about the facet. What the user doesn't
16
+ # supply, we'll make our best guess for.
17
+
18
+ facet = { }
19
+ facet[:model] = @object.klass
20
+
21
+ facet[:column] = facet[:model].content_columns.select { |x| x.name == column.to_s }
22
+
23
+ # Information about the column. This is used to generate the default
24
+ # label, and to pass the right selector to the Ransack fields.
25
+
26
+ facet[:column_name] = options[:column_name]
27
+ facet[:column_type] = options[:column_type]
28
+
29
+ # This is the type of field we will render. If this isn't provided, we'll
30
+ # determine this based on facet_column_type
31
+
32
+ facet[:type] = options[:type]
33
+
34
+ # In the specific case of facet_type == :collection, we'll allow the user
35
+ # to specify their own collection. If it's an association, we'll attempt
36
+ # to provide one.
37
+
38
+ facet[:collection] = options[:collection]
39
+
40
+ if facet[:column].empty? # facet doesn't exist
41
+
42
+ # Is it an association?
43
+ #
44
+ # We check for :singular_name, :plural_name and :singular_id
45
+
46
+ if association = associations_for(facet[:model]).select { |x|
47
+ x.plural_name == column.to_s or
48
+ x.plural_name.singularize == column.to_s or
49
+ x.primary_key_name == column.to_s }.uniq
50
+
51
+ if association.first.macro == :has_many
52
+
53
+ # For a has_many relationship, we want the plural name with _id.
54
+ # Ransack will then look at the _id column for the associated model.
55
+ # This won't work properly on models with nonstandard id column
56
+ # names. That's a problem, but whatevs for the time being.
57
+
58
+ facet[:column_name] = "#{association.first.plural_name}_id"
59
+
60
+ elsif association.first.macro == :belongs_to
61
+
62
+ # If we're dealing with belongs_to, we can assume we just want
63
+ # to look at the foreign key on the current model. Much simpler.
64
+
65
+ facet[:column_name] = association.first.foreign_key
66
+
67
+ end
68
+
69
+ # By default, we want to use a select box with a collection of
70
+ # what this model has_many of. If the user has specified something,
71
+ # we'll run with what they specified.
72
+
73
+ facet[:type] = facet[:type] || :collection
74
+
75
+ # If the user hasn't specified a collection, we'll provide one now
76
+ # based on this association
77
+
78
+ facet[:collection] = facet[:collection] || association.first.klass.all
79
+
80
+ else
81
+ return # nothing found
82
+ end
83
+ else
84
+
85
+ # We found a column. Let's yank some useful information out of it
86
+
87
+ facet[:column] = facet[:column].first
88
+ facet[:column_name] = facet[:column].name
89
+ facet[:column_type] = facet[:column_type] || facet[:column].type
90
+ end
91
+
92
+ facet[:type] = facet[:type] || default_facet_type(facet)
93
+
94
+
95
+ # Insert our label first
96
+
97
+ facet_html = "<div class=\"label #{additional_classes(facet)}\">"
98
+
99
+ if options[:label]
100
+ facet_html << self.label(column, options[:label])
101
+ else
102
+ facet_html << default_label_for_facet(facet)
103
+ end
104
+
105
+ facet_html << "</div>"
106
+
107
+ # And now the fields
108
+
109
+ facet_html << render_facet_for(facet)
110
+
111
+ facet_html.html_safe
112
+ end
113
+
114
+ # If the user doesn't pass options[:label], we'll build a default label
115
+ # based on the type of facet we're rendering.
116
+
117
+ def default_label_for_facet(facet)
118
+ case facet[:type]
119
+ when :cont
120
+ return self.label("#{facet[:column_name]}_cont".to_sym)
121
+ else
122
+ return self.label("#{facet[:column_name]}")
123
+ end
124
+ end
125
+
126
+ # Now that we have our type, we can render the actual form field for
127
+ # Ransack
128
+
129
+ def render_facet_for(facet)
130
+
131
+ facet_html = "<div class=\"input #{additional_classes(facet)}\">"
132
+
133
+ case facet[:type]
134
+ when :cont
135
+ facet_html << self.text_field("#{facet[:column_name]}_cont".to_sym)
136
+ when :collection
137
+ facet_html << self.collection_select("#{facet[:column_name]}_eq".to_sym, facet[:collection], :id, :to_s, :include_blank => true)
138
+ when :between
139
+ facet_html << "From "
140
+ facet_html << self.text_field("#{facet[:column_name]}_gteq".to_sym, :size => 11)
141
+ facet_html << "To "
142
+ facet_html << self.text_field("#{facet[:column_name]}_lteq".to_sym, :size => 11)
143
+ when :gteq
144
+ facet_html << self.text_field("#{facet[:column_name]}_gteq".to_sym, :size => 5)
145
+ when :lteq
146
+ facet_html << self.text_field("#{facet[:column_name]}_gteq".to_sym, :size => 5)
147
+ end
148
+
149
+ facet_html << "</div>"
150
+ facet_html
151
+ end
152
+
153
+ # If no options[:type] is specified, we'll look at the column type for
154
+ # the column in the model and make an educated guess.
155
+
156
+ def default_facet_type(facet)
157
+
158
+ case facet[:column_type]
159
+ when :string, :text
160
+ return :cont
161
+ when :datetime, :date, :float, :integer, :double
162
+ return :between
163
+ end
164
+ end
165
+
166
+ def additional_classes(facet)
167
+ additional_class = "#{facet[:type]} #{facet[:column_type]}"
168
+ end
169
+
170
+ # We can use reflections to determine has_many and belongs_to associations
171
+
172
+ def associations_for(model)
173
+ model.reflections.values
174
+ end
175
+
176
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: facet_for
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jonathan Barket
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-19 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ransack
16
+ requirement: &84397210 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *84397210
25
+ description: Provides helpers for creating search forms with Ransack
26
+ email:
27
+ - jbarket@sleepunit.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - Rakefile
35
+ - facet_for.gemspec
36
+ - lib/facet_for.rb
37
+ - lib/facet_for/version.rb
38
+ homepage: ''
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project: facet_for
58
+ rubygems_version: 1.8.10
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Provides helpers for creating search forms with Ransack
62
+ test_files: []