cat_forms 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5867215cad9448070b77390a76a9fe9e1fb390f9
4
- data.tar.gz: 6ebbcb9cfa9ed393b0ea4fb78f2cbe8554a2eadb
3
+ metadata.gz: e41399d5ac4893087435e2e6aa5955d4d3ee284a
4
+ data.tar.gz: b0a5e377693ef76d875bc2b87ce9495fb9e480de
5
5
  SHA512:
6
- metadata.gz: e3707d05035069c357604735aab2cb175df552e7570f550f37f5649865a78b0941443be2cbfb4e3e05ab03eef9053b13c3d1146226d9d00d1dae3f80dedba6d1
7
- data.tar.gz: 7c1efd9159019bde3397587177938c83d53967eb4c20c58a057c152482ea7816e6d8ea5c28687b4374cae9d2904895038c8fcadc73ab6032d4db55c5b198232d
6
+ metadata.gz: 3e721107373b10dfd0557b58b905fd3a6f58420e70ce11c3eace372f325643463b41796092bdc4fa8a86c1c96903dabed26431d0a4c5a5929d109ca0ca512cf7
7
+ data.tar.gz: cd56fde1729f815dbc07bd1e7057f71a81852076f15d188a5e777dbad12a67b2fb1c82e2b43e6c97f91f8bc738975c789b98a821aef49950b3fc9b9616210f8f
@@ -0,0 +1,35 @@
1
+ # encoding: UTF-8
2
+ require 'zlib'
3
+ require 'active_support/hash_with_indifferent_access'
4
+
5
+ # Saves form as cookie as json+gzip
6
+ module CatForms::GzipCookie
7
+ def self.load options={}
8
+ request = options[:request]
9
+ cookie_name = options[:cookie_name].to_s
10
+ result = ActiveSupport::HashWithIndifferentAccess.new
11
+ return result if request.blank?
12
+ cookie = request.cookies[cookie_name]
13
+ return result if cookie.nil? or cookie.empty?
14
+ begin
15
+ result.merge!(ActiveSupport::JSON.decode(Zlib::Inflate.inflate(cookie)).stringify_keys)
16
+ return result
17
+ rescue Zlib::DataError
18
+ return result
19
+ end
20
+ end
21
+
22
+ def self.save options = {}
23
+ attributes = options[:attributes]
24
+ response = options[:response]
25
+ cookie_name = options[:cookie_name]
26
+
27
+ cookie_json = ActiveSupport::JSON.encode(attributes)
28
+ cookie_json = Zlib::Deflate.deflate(cookie_json, Zlib::BEST_COMPRESSION)
29
+ cookie_hash = { value: cookie_json,
30
+ httponly: true,
31
+ }
32
+ response.set_cookie(cookie_name, cookie_hash)
33
+ end
34
+ end
35
+
@@ -0,0 +1,66 @@
1
+ require 'delegate'
2
+
3
+ module ValidationScopes
4
+ def self.included(base) # :nodoc:
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def validation_scope(scope)
10
+ @all_scopes ||= []
11
+ @all_scopes << scope
12
+
13
+ def self.all_scopes
14
+ @all_scopes
15
+ end
16
+
17
+ base_class = self
18
+
19
+ proxy_class = Class.new(DelegateClass(base_class)) do
20
+ include ActiveModel::Validations
21
+
22
+ def initialize(record)
23
+ @base_record = record
24
+ super(record)
25
+ end
26
+
27
+ # Hacks to support dynamic_model helpers
28
+ def to_model
29
+ self
30
+ end
31
+
32
+ # Rails 3 default implementation of model_name blows up for anonymous classes
33
+ class << self; self; end.class_eval do
34
+ define_method(:model_name) do
35
+ base_class.model_name
36
+ end
37
+ end
38
+ end
39
+
40
+ yield proxy_class
41
+
42
+ define_method(scope) do
43
+ send("validation_scope_proxy_for_#{scope}").errors
44
+ end
45
+
46
+ define_method("no_#{scope}?") do
47
+ send("validation_scope_proxy_for_#{scope}").valid?
48
+ end
49
+
50
+ define_method("has_#{scope}?") do
51
+ send("validation_scope_proxy_for_#{scope}").invalid?
52
+ end
53
+
54
+ define_method("init_validation_scope_for_#{scope}") do
55
+ unless instance_variable_defined?("@#{scope}")
56
+ instance_variable_set("@#{scope}", proxy_class.new(self))
57
+ end
58
+ end
59
+
60
+ define_method("validation_scope_proxy_for_#{scope}") do
61
+ send "init_validation_scope_for_#{scope}"
62
+ instance_variable_get("@#{scope}")
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,3 @@
1
+ module CatForms
2
+ VERSION = "0.0.3"
3
+ end
data/lib/cat_forms.rb ADDED
@@ -0,0 +1,254 @@
1
+ # Warning: This code is atrocious.
2
+ #
3
+ # ActiveModel is sorta confusing in Rails 3.2. I think
4
+ # it's improved in 4.0?
5
+ #
6
+ # TODO we should be checking the type of things when saving
7
+
8
+ module CatForms
9
+ require 'active_model'
10
+ require 'virtus'
11
+ require 'active_support/core_ext/class/attribute'
12
+ require 'cat_forms/validation_scopes'
13
+ autoload :GzipCookie, 'cat_forms/gzip_cookie'
14
+
15
+ # TODO not sure thy this is necessary. tests run, but
16
+ # when this is included by rails, i get already defined
17
+ # errors and super class mismatch errors.
18
+ if !defined?(CatForms::Boolean)
19
+ class Boolean < Virtus::Attribute::Boolean
20
+ end
21
+ end
22
+
23
+ module Form
24
+
25
+ def self.included base
26
+ base.send :include, ActiveModel::Validations
27
+ base.send :extend, ActiveModel::Callbacks
28
+ base.send :include, Virtus.model
29
+ base.send :extend, ClassMethods
30
+ base.send :include, InstanceMethods
31
+ base.send :include, ValidationScopes
32
+ base.instance_eval do
33
+ define_model_callbacks :initialize, :save
34
+ class_attribute :_form_name
35
+ end
36
+ end
37
+
38
+ module ClassMethods
39
+ # Overrides how Virtus handles attributes of the wrong type.
40
+ # Ideally virtus would coerce everything to the right type,
41
+ # use the default, or return nil.
42
+ # There's a related discussion here: https://github.com/solnic/virtus/issues/99
43
+ def attribute(name, type, opts = {})
44
+ super(name, type, opts)
45
+ define_method(name) do
46
+ data = super()
47
+ default_value = -> { opts[:default].respond_to?(:call) ? opts[:default].call : opts[:default] }
48
+
49
+ # If they want a BigDecimal or Int, but data is a string, strip
50
+ # the stuff of bad data and try to convert manually.
51
+ if type == BigDecimal or type == Integer
52
+ if data.class == String
53
+ data.gsub!(/[^\d\.]/, '')
54
+ if data.present?
55
+ if type == BigDecimal
56
+ data = BigDecimal.new(data)
57
+ else
58
+ data = Integer(data)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ #if type.class != Array and !data.is_a?(type) and !data.nil? and (type != CatForms::Boolean and !data.is_a?(Boolean))
65
+ #puts "cat forms expected a #{type} for #{ name }, received #{ data.inspect }"
66
+ #puts caller
67
+ #end
68
+
69
+ if type == CatForms::Boolean and (data == true or data == false)
70
+ return data
71
+ end
72
+
73
+ if type.class == Array
74
+ # Not validating more right now.
75
+ return data
76
+ end
77
+
78
+ if data.is_a?(type)
79
+ # Override for default string
80
+ if type == String and opts.has_key?(:default) and data == ""
81
+ return default_value.call
82
+ else
83
+ return data
84
+ end
85
+ end
86
+
87
+ return default_value.call
88
+ end
89
+ end
90
+
91
+ def form_name name
92
+ name = name.to_s
93
+
94
+ def name.i18n_key
95
+ self
96
+ end
97
+
98
+ def name.human
99
+ self
100
+ end
101
+
102
+ def name.singular
103
+ self
104
+ end
105
+
106
+ def name.plural
107
+ self
108
+ end
109
+
110
+ def name.param_key
111
+ self
112
+ end
113
+
114
+ self.class.instance_eval do
115
+ define_method :model_name do
116
+ name
117
+ end
118
+ end
119
+
120
+ self._form_name = name
121
+ end
122
+
123
+ def model_name
124
+ self._form_name || super
125
+ end
126
+
127
+ def form_attribute name, klass, options={}
128
+ # Setup the default values for each attribute.
129
+ if !options.has_key?(:default)
130
+ options[:default] =
131
+ if klass.kind_of?(Array)
132
+ []
133
+ elsif klass == BigDecimal or klass == Boolean or klass == CatForms::Boolean
134
+ nil
135
+ elsif klass.respond_to?(:new)
136
+ proc { klass.new }
137
+ else
138
+ nil
139
+ end
140
+ end
141
+ attribute name, klass, options
142
+ if options[:validations]
143
+ validates(name, options[:validations])
144
+ end
145
+
146
+ # Define an association_attributes= method
147
+ # Rails's fields_for looks for this.
148
+ if klass.kind_of?(Array)
149
+ define_method "#{name}_attributes=" do |hash|
150
+ hash.each do |_index, opts|
151
+ # If the array is nil, set it to an empty array.
152
+ self.send("#{name}=", []) if self.send(name).nil?
153
+ self.send(name) << klass.first.new(opts)
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ def custom_attribute attribute_name
160
+ class_eval do
161
+ attr_reader attribute_name
162
+ end
163
+ end
164
+
165
+ def validates_associated(*associations)
166
+ validates_each(associations) do |record, _associate_name, value|
167
+ (value.respond_to?(:each) ? value : [value]).each do |rec|
168
+ if rec && !rec.valid?
169
+ rec.errors.each do |key, val|
170
+ record.errors.add(key, val)
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ module InstanceMethods
179
+ # Need to look into all the below methods, not sure if they are
180
+ # correct.
181
+ def persisted?
182
+ false
183
+ end
184
+
185
+ def to_model
186
+ self
187
+ end
188
+
189
+ def to_partial_path
190
+ "some_path" # TODO figure out what's needed here for Rails 3.2
191
+ end
192
+
193
+ def to_param
194
+ nil
195
+ end
196
+
197
+ def to_key
198
+ nil
199
+ end
200
+
201
+ def save
202
+ run_callbacks :save do
203
+ if !valid?
204
+ return false
205
+ end
206
+ end
207
+ self
208
+ end
209
+
210
+ def initialize options = {}
211
+ run_callbacks(:initialize) do
212
+ # can sometimes be a string
213
+ if options.class != Hash
214
+ options = {}
215
+ end
216
+ options[:form] ||= {}
217
+
218
+ # TODO fix
219
+ # This allows setting of custom things
220
+ options.each do |key, value|
221
+ instance_variable_set "@#{key}", value
222
+ end
223
+
224
+ CatForms::GzipCookie.load(storage_options).each do |key, value|
225
+ method = "#{key}="
226
+ if respond_to?(method)
227
+ self.send method, value
228
+ end
229
+ end
230
+
231
+ options[:form].each do |name, value|
232
+ value.strip! if value.respond_to?(:strip)
233
+ self.send "#{name}=", value
234
+ end
235
+
236
+ end
237
+ super
238
+ end
239
+
240
+ def save_to_storage!
241
+ options = storage_options.merge(attributes: attributes)
242
+ CatForms::GzipCookie.save(options)
243
+ end
244
+
245
+ def storage_options
246
+ {
247
+ cookie_name: @cookie_name,
248
+ request: @request,
249
+ response: @response
250
+ }
251
+ end
252
+ end
253
+ end
254
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cat_forms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Van Dyk
@@ -44,7 +44,11 @@ email:
44
44
  executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
- files: []
47
+ files:
48
+ - lib/cat_forms.rb
49
+ - lib/cat_forms/gzip_cookie.rb
50
+ - lib/cat_forms/validation_scopes.rb
51
+ - lib/cat_forms/version.rb
48
52
  homepage: https://github.com/joevandyk/cat_forms
49
53
  licenses: []
50
54
  metadata: {}