rails_stuff 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +24 -0
- data/.travis.yml +8 -0
- data/Gemfile +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +350 -0
- data/Rakefile +22 -0
- data/bin/console +7 -0
- data/bin/git-hooks/pre-commit +14 -0
- data/bin/install_git_hooks +8 -0
- data/bin/setup +8 -0
- data/lib/net/http/debug.rb +26 -0
- data/lib/rails_stuff/helpers/all.rb +12 -0
- data/lib/rails_stuff/helpers/bootstrap.rb +34 -0
- data/lib/rails_stuff/helpers/forms.rb +21 -0
- data/lib/rails_stuff/helpers/links.rb +38 -0
- data/lib/rails_stuff/helpers/resource_form.rb +49 -0
- data/lib/rails_stuff/helpers/text.rb +28 -0
- data/lib/rails_stuff/helpers/translation.rb +29 -0
- data/lib/rails_stuff/helpers.rb +14 -0
- data/lib/rails_stuff/nullify_blank_attrs.rb +23 -0
- data/lib/rails_stuff/params_parser.rb +121 -0
- data/lib/rails_stuff/railtie.rb +54 -0
- data/lib/rails_stuff/random_uniq_attr.rb +48 -0
- data/lib/rails_stuff/redis_storage.rb +119 -0
- data/lib/rails_stuff/resources_controller/actions.rb +31 -0
- data/lib/rails_stuff/resources_controller/basic_helpers.rb +161 -0
- data/lib/rails_stuff/resources_controller/resource_helper.rb +31 -0
- data/lib/rails_stuff/resources_controller/responder.rb +21 -0
- data/lib/rails_stuff/resources_controller/sti_helpers.rb +62 -0
- data/lib/rails_stuff/resources_controller.rb +42 -0
- data/lib/rails_stuff/sort_scope.rb +71 -0
- data/lib/rails_stuff/statusable.rb +130 -0
- data/lib/rails_stuff/test_helpers/rails.rb +6 -0
- data/lib/rails_stuff/test_helpers/response.rb +34 -0
- data/lib/rails_stuff/types_tracker.rb +50 -0
- data/lib/rails_stuff/version.rb +14 -0
- data/lib/rails_stuff.rb +19 -0
- data/rails_stuff.gemspec +25 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 82159ba1a8b42ef1cea7d901d966408ae47dc832
|
4
|
+
data.tar.gz: c4d212a0f28c39142139945488c73c7c5eb10eb4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 767e814c2d06cc0ec03988d0a5a510edeba5407310a3d72c1592ff6e947fb4ee58adba0ad0efa6ee2d0e33a8fbd0d58c5a250a900d2fd5bbb766c7b067028443
|
7
|
+
data.tar.gz: 49ce30b733a8a28ab71dcb6a7cafd496f74f391000f52ae9597be8605810564b781bfc838dff3f92ad8f60d922d6f8ecbf00a99d77390c929caf1a8d4bae3f60
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
AllCops:
|
2
|
+
RunRailsCops: true
|
3
|
+
|
4
|
+
Style/AlignParameters:
|
5
|
+
# Disable, till rubocop supports combination of styles.
|
6
|
+
# Use one of this styles where appropriate, keep it clean, compact and readable.
|
7
|
+
Enabled: false
|
8
|
+
EnforcedStyle:
|
9
|
+
- aligned
|
10
|
+
- with_fixed_indentation
|
11
|
+
Style/ClosingParenthesisIndentation: {Enabled: false}
|
12
|
+
Style/Documentation: {Enabled: false}
|
13
|
+
Style/DotPosition: {EnforcedStyle: trailing}
|
14
|
+
Style/IfUnlessModifier: {Enabled: false}
|
15
|
+
Style/ModuleFunction: {Enabled: false}
|
16
|
+
Style/MultilineOperationIndentation: {EnforcedStyle: indented}
|
17
|
+
Style/PredicateName: {Enabled: false}
|
18
|
+
Style/SignalException: {EnforcedStyle: only_raise}
|
19
|
+
Style/SpaceInsideHashLiteralBraces: {EnforcedStyle: no_space}
|
20
|
+
Style/TrailingComma: {Enabled: false}
|
21
|
+
|
22
|
+
Metrics/AbcSize: {Max: 19}
|
23
|
+
Metrics/LineLength: {Max: 100}
|
24
|
+
Metrics/MethodLength: {Max: 30}
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
gemspec
|
3
|
+
|
4
|
+
group :development do
|
5
|
+
gem 'sdoc', '~> 0.4.1'
|
6
|
+
gem 'pry', '~> 0.10.1'
|
7
|
+
|
8
|
+
gem 'sqlite3', '~> 1.3.10'
|
9
|
+
gem 'database_cleaner', '~> 1.5.0'
|
10
|
+
gem 'pooled_redis', '~> 0.2.1'
|
11
|
+
gem 'activemodel_translation', '~> 0.1.0'
|
12
|
+
gem 'has_scope', '~> 0.6.0'
|
13
|
+
gem 'responders', '~> 2.1.0'
|
14
|
+
gem 'kaminari', '~> 0.16.3'
|
15
|
+
|
16
|
+
gem 'rspec', '~> 3.3.0'
|
17
|
+
gem 'rspec-its', '~> 1.1.0'
|
18
|
+
gem 'rspec-rails', '~> 3.3.3'
|
19
|
+
|
20
|
+
gem 'rubocop', '~> 0.33.0'
|
21
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Max Melentiev
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,350 @@
|
|
1
|
+
# RailsStuff
|
2
|
+
[](http://badge.fury.io/rb/rails_stuff)
|
3
|
+
[](https://codeclimate.com/github/printercu/rails_stuff)
|
4
|
+
[](https://travis-ci.org/printercu/rails_stuff)
|
5
|
+
|
6
|
+
Collection of useful modules for Rails.
|
7
|
+
|
8
|
+
#### Controllers:
|
9
|
+
|
10
|
+
- __[ResourcesController](#resourcescontroller)__
|
11
|
+
DRY! Keep your controllers clean.
|
12
|
+
- __[SortScope](#sortscope)__
|
13
|
+
Helper for `has_scope` to sort collections safely.
|
14
|
+
|
15
|
+
#### Models:
|
16
|
+
|
17
|
+
- __[NullifyBlankAttrs](#nullifyblankattrs)__
|
18
|
+
Proxies writers to replace empty values with `nil`.
|
19
|
+
- __[RandomUniqAttr](#randomuniqattr)__
|
20
|
+
You generate random values for attributes, it'll ensure they are uniq.
|
21
|
+
- __[Statusable](#statusable)__
|
22
|
+
`ActiveRecord::Enum` with more features.
|
23
|
+
- __[TypesTracker](#typestracker)__
|
24
|
+
Advanced descendants tracker.
|
25
|
+
|
26
|
+
#### Misc:
|
27
|
+
|
28
|
+
- __[ParamsParser](#paramsparser)__
|
29
|
+
Type-cast params outside of `ActiveRecord`.
|
30
|
+
- __[RedisStorage](#redisstorage)__
|
31
|
+
Simple way to store collections in key-value storage. With scoping and
|
32
|
+
key generation.
|
33
|
+
|
34
|
+
#### Helpers:
|
35
|
+
|
36
|
+
- __TranslationHelper__
|
37
|
+
`translate_action`, `translate_confirmation` helpers to translate
|
38
|
+
action names and confirmations in the same way all over you app.
|
39
|
+
- __LinksHelper__
|
40
|
+
Keep your links for basic actions consistent.
|
41
|
+
- __Bootstrap__
|
42
|
+
For bootstrap-formatted flash messages.
|
43
|
+
- __Forms__
|
44
|
+
`hidden_params_fields` to bypass query params in GET-forms.
|
45
|
+
|
46
|
+
__[Helpers usage](#helpers)__
|
47
|
+
|
48
|
+
## Installation
|
49
|
+
|
50
|
+
Add this line to your application's Gemfile:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
gem 'rails_stuff'
|
54
|
+
```
|
55
|
+
|
56
|
+
And then execute:
|
57
|
+
|
58
|
+
$ bundle
|
59
|
+
|
60
|
+
Or install it yourself as:
|
61
|
+
|
62
|
+
$ gem install rails_stuff
|
63
|
+
|
64
|
+
## Usage
|
65
|
+
|
66
|
+
All modules are lazy loaded, so it's ok to require whole gem at once.
|
67
|
+
There is railtie which will include some of modules into `ActiveRecord::Base`
|
68
|
+
and `ActionController::Base` by default. You can disable this behavior in
|
69
|
+
initializer:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
# Disable auto-setup:
|
73
|
+
RailsStuff.load_modules = []
|
74
|
+
|
75
|
+
# Enable particular modules:
|
76
|
+
RailsStuff.load_modules = %i(sort_scope statusable)
|
77
|
+
```
|
78
|
+
|
79
|
+
You can override base classes for controller/model with `.base_controller=`,
|
80
|
+
`.base_model=`.
|
81
|
+
|
82
|
+
Works only with ruby 2.0+, tested with Rails 4.2.
|
83
|
+
|
84
|
+
There can be lack of documentation in README. Please navigate to module and
|
85
|
+
check docs & code (press `t` on github) if you miss something.
|
86
|
+
|
87
|
+
### ResourcesController
|
88
|
+
|
89
|
+
Similar to [InheriteResource](https://github.com/josevalim/inherited_resources)
|
90
|
+
but much simpler. It adds implementations for basic actions and
|
91
|
+
accessors for collection and resource. There is no options for almost everything,
|
92
|
+
but it's easy to extend.
|
93
|
+
|
94
|
+
It's main purpose is to ged rid of `@user ||= User.find params[:id]`, and keep
|
95
|
+
controllers clean:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
class ApplicationController < ActionController::Base
|
99
|
+
extend RailsStuff::ResourcesController # when using without railtie
|
100
|
+
end
|
101
|
+
|
102
|
+
class UsersController < ApplicationController
|
103
|
+
resources_controller
|
104
|
+
permit_attrs :name, :email
|
105
|
+
end
|
106
|
+
|
107
|
+
class ProjectsController < ApplicationController
|
108
|
+
resources_controller sti: true,
|
109
|
+
after_save_action: :index,
|
110
|
+
source_relation: -> { user.projects }
|
111
|
+
resource_helper :user
|
112
|
+
permit_attrs :name
|
113
|
+
permit_attrs_for Project::External, :company
|
114
|
+
permit_attrs_for Project::Internal, :department
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
There is built-in support for pagination with Kaminari.
|
119
|
+
It's enabled automatically if `kaminari` gem is loaded.
|
120
|
+
|
121
|
+
Currently depends on `gem 'responders', '> 2.0'`.
|
122
|
+
|
123
|
+
### SortScope
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
# in controller
|
127
|
+
extend RailsStuff::SortScope # when using without railtie
|
128
|
+
|
129
|
+
sort_scope by: [:name, :created_at, :balance], default: [:name]
|
130
|
+
|
131
|
+
# this scope will accept
|
132
|
+
# - `sort=name`
|
133
|
+
# - `sort=name&sort_desc=true`
|
134
|
+
# - `sort[name]&sort[created_at]`
|
135
|
+
# - `sort[name]&sort[created_at]=desc
|
136
|
+
```
|
137
|
+
|
138
|
+
Requires `gem 'has_scope'`.
|
139
|
+
|
140
|
+
### NullifyBlankAttrs
|
141
|
+
|
142
|
+
Defines proxies for writers to replace empty values with `nil`.
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
# in model
|
146
|
+
extend RailsStuff::NullifyBlankAttrs # when using without railtie
|
147
|
+
|
148
|
+
nullify_blank_attrs :email, :title
|
149
|
+
```
|
150
|
+
|
151
|
+
### RandomUniqAttr
|
152
|
+
|
153
|
+
Uses database's UNIQUE constraints and transactions to generate uniq random values.
|
154
|
+
You need to make field nullable and add unique index on it.
|
155
|
+
The way it works:
|
156
|
+
|
157
|
+
- Instance is saved as usual
|
158
|
+
- If random fields are not empty, it does nothing
|
159
|
+
- Generates random value and tries to update instance
|
160
|
+
- If `RecordNotUnique` is occurred, it keeps trying to generate new values.
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
# in model
|
164
|
+
extend RailsStuff::RandomUniqAttr # when using without railtie
|
165
|
+
|
166
|
+
# Uses DEFAULT_GENERATOR which is SecureRandom(32)
|
167
|
+
random_uniq_attr :token
|
168
|
+
|
169
|
+
# Uses custom generator, which takes template from settings
|
170
|
+
random_uniq_attr(:code) do |instance|
|
171
|
+
MyGenerator.generate(instance.parent.code_template)
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
### Statusable
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
class User < ActiveRecord::Base
|
179
|
+
extend RailsStuff::RandomUniqAttr # when using without railtie
|
180
|
+
|
181
|
+
STATUSES = %i(confirmed banned)
|
182
|
+
has_status_field # uses #status field and STATUSES as values
|
183
|
+
|
184
|
+
# Or pass everything explicitly
|
185
|
+
has_status_field :subscription_status, %i(expired active), prefix: :subs_
|
186
|
+
# :prefix is used for methods that are build
|
187
|
+
end
|
188
|
+
|
189
|
+
user = User.first
|
190
|
+
|
191
|
+
# And you get:
|
192
|
+
# Scopes
|
193
|
+
User.confirmed.subs_active
|
194
|
+
User.not_banned.not_subs_expired
|
195
|
+
# Useful with has_scope
|
196
|
+
User.with_status(param[:status]).with_subscription_status(params[:subs_status])
|
197
|
+
|
198
|
+
# Translation & select helpers (requires activemodel_translation gem)
|
199
|
+
User.status_name(:active)
|
200
|
+
user.subscription_status_name # translates current status
|
201
|
+
User.status_select_options
|
202
|
+
User.subscription_status_select_options except: [:expired]
|
203
|
+
|
204
|
+
# Accessors
|
205
|
+
user.status = 'confirmed' or user.confirmed!
|
206
|
+
user.status_sym # :confirmed
|
207
|
+
user.subscription_status = :active or user.subs_active!
|
208
|
+
user.subscription_status # 'active'
|
209
|
+
user.banned? or user.subs_expired?
|
210
|
+
|
211
|
+
# ... and inclusion validator
|
212
|
+
```
|
213
|
+
|
214
|
+
### TypesTracker
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
class Project
|
218
|
+
extend RailsStuff::TypesTracker
|
219
|
+
# you can also override default list class (Array) with:
|
220
|
+
self.types_list_class = FilterableArray
|
221
|
+
# smth ...
|
222
|
+
|
223
|
+
# If you want to show all available descendants in development
|
224
|
+
# (ex. in dropdown/select), you definitely want this:
|
225
|
+
eager_load_types! # will load all files in app/models/project
|
226
|
+
# or pass folder explicitly:
|
227
|
+
eager_load_types!('lib/path/to/projects')
|
228
|
+
end
|
229
|
+
|
230
|
+
class Project::Big < Project
|
231
|
+
unregister_type # remove this class from types_list
|
232
|
+
|
233
|
+
# Or add options for custom list.
|
234
|
+
# Following will call types_list.add Project::Big, :arg, option: :example
|
235
|
+
register_type :arg, option: :example
|
236
|
+
end
|
237
|
+
|
238
|
+
class Project::Internal < Project::Big; end
|
239
|
+
class Project::External < Project::Big; end
|
240
|
+
class Project::Small < Project; end
|
241
|
+
|
242
|
+
Project.types_list # [Internal, External, Small]
|
243
|
+
```
|
244
|
+
|
245
|
+
### ParamsParser
|
246
|
+
|
247
|
+
Have you missed type-casting outside of `ActiveRecord::Base`? Here is it:
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
ParamsParser.parse_int(params[:field]) # _float, _string, _boolean, _datetime
|
251
|
+
ParamsParser.parse_int_array(params[:field_with_array])
|
252
|
+
ParamsParser.parse_json(json_string)
|
253
|
+
|
254
|
+
# There is basic .parse method. It runs block only if input is not nil
|
255
|
+
# and reraises all errors with ParamsParser::Error
|
256
|
+
ParamsParser.parse(input) { |x| this_can_raise_exception(x) }
|
257
|
+
|
258
|
+
# So you can handle all errors in controller with
|
259
|
+
rescue_from ParamsParser::Error, with: -> { head :bad_request }
|
260
|
+
```
|
261
|
+
|
262
|
+
### RedisStorage
|
263
|
+
|
264
|
+
Simple module to organize data in key-value store. Uses `ConnectionPool`
|
265
|
+
and works good in multi-threaded environments.
|
266
|
+
Best used with [PooledRedis](https://github.com/printercu/pooled_redis).
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
class Model
|
270
|
+
extend RailsStuff::SedisStorage
|
271
|
+
|
272
|
+
self.redis_prefix = :other_prefix # default to underscored model name
|
273
|
+
|
274
|
+
# override .dump, .load for custom serialization. Default to Marshal
|
275
|
+
|
276
|
+
# It uses Rails.redis_pool by default. Override it with
|
277
|
+
self.redis_pool = ConnectionPool.new { Redis.new(my_options) }
|
278
|
+
end
|
279
|
+
|
280
|
+
Model.get('key') # GET other_prefix:key
|
281
|
+
Model.get(['composite', 'key']) # GET other_prefix:composite:key
|
282
|
+
# .delete works the same way
|
283
|
+
|
284
|
+
Model.set('key', data) or Model.set(['composite', 'key'], data)
|
285
|
+
next_id = Model.set(nil, data) # auto-incremented per-model id
|
286
|
+
next_id = Model.set(['composite', nil], data) # auto-incremented per-scope id
|
287
|
+
Model.set(id, data, ex: 10) # pass options for redis
|
288
|
+
# Or set per-model options for all .set requests:
|
289
|
+
Model.redis_set_options = {ex: 10}
|
290
|
+
|
291
|
+
# generate ids:
|
292
|
+
Model.next_id or Model.next_id(['composite', 'scope'])
|
293
|
+
Model.reset_id_seq or Model.reset_id_seq(['composite', 'scope'])
|
294
|
+
```
|
295
|
+
|
296
|
+
### Helpers
|
297
|
+
|
298
|
+
Include helper module into `ApplicationHelper`.
|
299
|
+
Or use `RailsStuff::Helpers::All` to include all helpers together.
|
300
|
+
|
301
|
+
Add this sections to your translations ymls:
|
302
|
+
|
303
|
+
```yml
|
304
|
+
helpers:
|
305
|
+
actions:
|
306
|
+
edit: Change
|
307
|
+
delete: Forget about it
|
308
|
+
confirm: Really?
|
309
|
+
confirmations:
|
310
|
+
delete: Will you miss it?
|
311
|
+
```
|
312
|
+
|
313
|
+
And use helpers:
|
314
|
+
|
315
|
+
```ruby
|
316
|
+
translate_action(:edit) or translate_action(:delete)
|
317
|
+
link_to 'x', url_for(resource),
|
318
|
+
method: :delete, data: {confirm: translate_confirmation(:delete)}
|
319
|
+
translate_confirmation(:purge_all) # Fallback to default: 'Really?'
|
320
|
+
|
321
|
+
# There are helpers for basic links, take a look on helpers/links.rb to know
|
322
|
+
# how to tune it:
|
323
|
+
link_to_edit or link_to_edit('url') or link_to_edit([:scope, resource])
|
324
|
+
link_to_destroy or link_to_destroy('url') or link_to_destroy([:scope, resource])
|
325
|
+
```
|
326
|
+
|
327
|
+
Translation helpers are cached, so there is no need to cache it by yourself in
|
328
|
+
template if you want to decrease computations. And be aware of it if you
|
329
|
+
switch locales while rendering single view.
|
330
|
+
|
331
|
+
## Development
|
332
|
+
|
333
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
334
|
+
Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
335
|
+
|
336
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
337
|
+
To release a new version, update the version number in `version.rb`,
|
338
|
+
and then run `bundle exec rake release` to create a git tag for the version,
|
339
|
+
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
340
|
+
|
341
|
+
## Contributing
|
342
|
+
|
343
|
+
1. Fork it ( https://github.com/printercu/rails_stuff/fork )
|
344
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
345
|
+
3. Implement your feature:
|
346
|
+
- Write failing spec for your feature
|
347
|
+
- Write code
|
348
|
+
- Commit your changes (`git commit -am 'Add some feature'`)
|
349
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
350
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task default: :spec
|
7
|
+
|
8
|
+
require 'sdoc'
|
9
|
+
RDoc::Task.new(:doc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'doc'
|
11
|
+
|
12
|
+
rdoc.title = 'RailsStuff'
|
13
|
+
|
14
|
+
rdoc.options << '--markup' << 'markdown'
|
15
|
+
rdoc.options << '-e' << 'UTF-8'
|
16
|
+
rdoc.options << '--format' << 'sdoc'
|
17
|
+
rdoc.options << '--template' << 'rails'
|
18
|
+
rdoc.options << '--all'
|
19
|
+
|
20
|
+
rdoc.rdoc_files.include('README.md')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
pattern=$(echo -n '\.rb
|
4
|
+
\.gemspec
|
5
|
+
\.jbuilder
|
6
|
+
\.rake
|
7
|
+
config\.ru
|
8
|
+
Gemfile
|
9
|
+
Rakefile' | tr "\\n" '|')
|
10
|
+
|
11
|
+
files=`git diff --cached --name-status | grep -E "^[AM].*($pattern)$" | cut -f2-`
|
12
|
+
if [ -n "$files" ]; then
|
13
|
+
bundle exec rubocop $files --force-exclusion
|
14
|
+
fi
|
data/bin/setup
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
class << Net::HTTP
|
4
|
+
# Redefines `.new` to set debug device for all new instances.
|
5
|
+
def debug!(out = $stderr)
|
6
|
+
return if respond_to?(:__new__)
|
7
|
+
class << self
|
8
|
+
alias_method :__new__, :new
|
9
|
+
end
|
10
|
+
|
11
|
+
define_singleton_method :new do |*args, &blk|
|
12
|
+
instance = __new__(*args, &blk)
|
13
|
+
instance.set_debug_output(out)
|
14
|
+
instance
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Restores original `.new`.
|
19
|
+
def disable_debug!
|
20
|
+
return unless respond_to?(:__new__)
|
21
|
+
class << self
|
22
|
+
alias_method :new, :__new__
|
23
|
+
remove_method :__new__
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
require 'active_support/core_ext/hash/transform_values'
|
3
|
+
|
4
|
+
module RailsStuff
|
5
|
+
module Helpers
|
6
|
+
module Bootstrap
|
7
|
+
BOOTSTRAP_FLASH_TYPE = {
|
8
|
+
success: 'alert-success',
|
9
|
+
error: 'alert-danger',
|
10
|
+
alert: 'alert-warning',
|
11
|
+
notice: 'alert-info',
|
12
|
+
}.stringify_keys.freeze
|
13
|
+
|
14
|
+
def flash_messages
|
15
|
+
flash.map do |type, message|
|
16
|
+
content_tag :div, class: [:alert, BOOTSTRAP_FLASH_TYPE[type] || type] do
|
17
|
+
content_tag(:button, '×'.html_safe, class: :close, data: {dismiss: :alert}) +
|
18
|
+
simple_format(message)
|
19
|
+
end
|
20
|
+
end.join.html_safe
|
21
|
+
end
|
22
|
+
|
23
|
+
ICONS = {
|
24
|
+
destroy: %(<span class='glyphicon icon-destroy'></span>),
|
25
|
+
edit: %(<span class='glyphicon icon-edit'></span>),
|
26
|
+
new: %(<span class='glyphicon icon-add'></span>),
|
27
|
+
}.tap { |x| x.transform_values!(&:html_safe) if ''.respond_to?(:html_safe) }
|
28
|
+
|
29
|
+
def basic_link_icons
|
30
|
+
ICONS
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RailsStuff
|
2
|
+
module Helpers
|
3
|
+
module Forms
|
4
|
+
# Returns hidden field tags for requested fields when they are present in params.
|
5
|
+
# Usually used to bypass params in GET-forms.
|
6
|
+
def hidden_params_fields(*fields)
|
7
|
+
inputs = fields.flat_map do |field|
|
8
|
+
next unless params.key?(field)
|
9
|
+
val = params[field]
|
10
|
+
if val.is_a?(Array)
|
11
|
+
name = "#{field}[]"
|
12
|
+
val.map { |str| [name, str] }
|
13
|
+
else
|
14
|
+
[[field, val]]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
safe_join inputs.map { |(name, val)| hidden_field_tag name, val if name }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RailsStuff
|
2
|
+
module Helpers
|
3
|
+
# Link helpers for basic actions.
|
4
|
+
module Links
|
5
|
+
ICONS = {
|
6
|
+
destroy: -> { translate_action(:destroy) },
|
7
|
+
edit: -> { translate_action(:edit) },
|
8
|
+
new: -> { translate_action(:new) },
|
9
|
+
}
|
10
|
+
|
11
|
+
def basic_link_icons
|
12
|
+
ICONS
|
13
|
+
end
|
14
|
+
|
15
|
+
def basic_link_icon(action)
|
16
|
+
val = basic_link_icons[action]
|
17
|
+
val.is_a?(Proc) ? instance_exec(&val) : val
|
18
|
+
end
|
19
|
+
|
20
|
+
def link_to_destroy(url, **options)
|
21
|
+
link_to basic_link_icon(:destroy), url, {
|
22
|
+
title: translate_action(:delete),
|
23
|
+
method: :delete,
|
24
|
+
data: {confirm: translate_confirmation(:delete)},
|
25
|
+
}.merge!(options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def link_to_edit(url = nil, **options)
|
29
|
+
link_to basic_link_icon(:edit), (url || url_for(action: :edit)),
|
30
|
+
{title: translate_action(:edit)}.merge!(options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def link_to_new(url = nil, **options)
|
34
|
+
link_to basic_link_icon(:new), (url || url_for(action: :new)), options
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|