openstax_connect 0.0.10 → 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.
Files changed (62) hide show
  1. data/README.md +26 -9
  2. data/Rakefile +12 -39
  3. data/app/controllers/openstax/connect/application_controller.rb +15 -4
  4. data/app/controllers/openstax/connect/dev/dev_controller.rb +1 -4
  5. data/app/controllers/openstax/connect/dev/users_controller.rb +5 -0
  6. data/app/controllers/openstax/connect/sessions_controller.rb +9 -19
  7. data/app/handlers/openstax/connect/sessions_omniauth_authenticated.rb +4 -1
  8. data/app/views/openstax/connect/dev/users/login.html.erb +2 -2
  9. data/app/views/openstax/connect/dev/users/search.js.erb +1 -1
  10. data/config/initializers/{02_extend_builtins.rb → extend_builtins.rb} +0 -0
  11. data/config/routes.rb +11 -6
  12. data/db/migrate/20140410194004_add_fields_to_openstax_connect_users.rb +7 -0
  13. data/lib/omniauth/strategies/openstax.rb +15 -6
  14. data/lib/openstax/connect/current_user_manager.rb +3 -3
  15. data/lib/openstax/connect/engine.rb +1 -4
  16. data/lib/openstax/connect/inflections.rb +3 -0
  17. data/lib/openstax/connect/version.rb +1 -1
  18. data/lib/openstax_connect.rb +52 -6
  19. data/spec/controllers/openstax/connect/dev/users_controller_spec.rb +20 -0
  20. data/spec/controllers/openstax/connect/sessions_controller_spec.rb +21 -7
  21. data/spec/dummy/README.md +1 -0
  22. data/spec/dummy/Rakefile +7 -0
  23. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  24. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  25. data/spec/dummy/app/controllers/api/application_users_controller.rb +7 -0
  26. data/spec/dummy/app/controllers/api/dummy_controller.rb +11 -0
  27. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  28. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  29. data/spec/dummy/config.ru +4 -0
  30. data/spec/dummy/config/application.rb +53 -0
  31. data/spec/dummy/config/boot.rb +10 -0
  32. data/spec/dummy/config/database.yml +25 -0
  33. data/spec/dummy/config/environment.rb +5 -0
  34. data/spec/dummy/config/environments/development.rb +29 -0
  35. data/spec/dummy/config/environments/production.rb +69 -0
  36. data/spec/dummy/config/environments/test.rb +35 -0
  37. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  38. data/spec/dummy/config/initializers/inflections.rb +15 -0
  39. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  40. data/spec/dummy/config/initializers/openstax_connect.rb +11 -0
  41. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  42. data/spec/dummy/config/initializers/session_store.rb +8 -0
  43. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  44. data/spec/dummy/config/locales/en.yml +5 -0
  45. data/spec/dummy/config/routes.rb +11 -0
  46. data/spec/dummy/db/schema.rb +31 -0
  47. data/spec/dummy/public/404.html +26 -0
  48. data/spec/dummy/public/422.html +26 -0
  49. data/spec/dummy/public/500.html +25 -0
  50. data/spec/dummy/public/favicon.ico +0 -0
  51. data/spec/dummy/script/rails +6 -0
  52. data/spec/lib/openstax_connect_spec.rb +24 -0
  53. data/spec/models/openstax/connect/user_spec.rb +7 -1
  54. data/spec/spec_helper.rb +7 -4
  55. metadata +109 -17
  56. data/app/assets/javascripts/openstax/connect/sessions.js +0 -2
  57. data/app/assets/stylesheets/openstax/connect/sessions.css +0 -4
  58. data/app/helpers/openstax/connect/sessions_helper.rb +0 -4
  59. data/config/initializers/01_requires.rb +0 -1
  60. data/lib/openstax/connect/exceptions.rb +0 -3
  61. data/lib/tasks/connect-rails_tasks.rake +0 -4
  62. data/spec/helpers/openstax/connect/sessions_helper_spec.rb +0 -17
@@ -0,0 +1,14 @@
1
+ # Be sure to restart your server when you modify this file.
2
+ #
3
+ # This file contains settings for ActionController::ParamsWrapper which
4
+ # is enabled by default.
5
+
6
+ # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7
+ ActiveSupport.on_load(:action_controller) do
8
+ wrap_parameters format: [:json]
9
+ end
10
+
11
+ # Disable root element in JSON by default.
12
+ ActiveSupport.on_load(:active_record) do
13
+ self.include_root_in_json = false
14
+ end
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
@@ -0,0 +1,11 @@
1
+ Rails.application.routes.draw do
2
+ mount OpenStax::Connect::Engine => "/connect"
3
+
4
+ namespace :api do
5
+ post "dummy", :to => "dummy#dummy"
6
+
7
+ resource :application_users, :only => :create
8
+ end
9
+
10
+ root :to => "application#index"
11
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended to check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(:version => 20140410194004) do
15
+
16
+ create_table "openstax_connect_users", :force => true do |t|
17
+ t.integer "openstax_uid"
18
+ t.string "first_name"
19
+ t.string "last_name"
20
+ t.string "username"
21
+ t.datetime "created_at", :null => false
22
+ t.datetime "updated_at", :null => false
23
+ t.string "full_name"
24
+ t.string "title"
25
+ t.string "access_token"
26
+ end
27
+
28
+ add_index "openstax_connect_users", ["openstax_uid"], :name => "index_openstax_connect_users_on_openstax_uid", :unique => true
29
+ add_index "openstax_connect_users", ["username"], :name => "index_openstax_connect_users_on_username", :unique => true
30
+
31
+ end
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/404.html -->
21
+ <div class="dialog">
22
+ <h1>The page you were looking for doesn't exist.</h1>
23
+ <p>You may have mistyped the address or the page may have moved.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/422.html -->
21
+ <div class="dialog">
22
+ <h1>The change you wanted was rejected.</h1>
23
+ <p>Maybe you tried to change something you didn't have access to.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/500.html -->
21
+ <div class="dialog">
22
+ <h1>We're sorry, but something went wrong.</h1>
23
+ </div>
24
+ </body>
25
+ </html>
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,24 @@
1
+ module OpenStax
2
+ describe Connect do
3
+ let!(:user) { OpenStax::Connect::User.create(username: 'some_user',
4
+ openstax_uid: 1,
5
+ access_token: 'secret') }
6
+
7
+ it 'makes api calls' do
8
+ expect(Api::DummyController.last_action).to be_nil
9
+ expect(Api::DummyController.last_params).to be_nil
10
+ Connect.api_call(:post, 'dummy', :access_token => user.access_token,
11
+ :params => {:test => true})
12
+ expect(Api::DummyController.last_action).to eq :dummy
13
+ expect(Api::DummyController.last_params).to include 'test' => 'true'
14
+ end
15
+
16
+ it 'makes api call to create application_user' do
17
+ expect(Api::ApplicationUsersController.last_action).to be_nil
18
+ expect(Api::ApplicationUsersController.last_params).to be_nil
19
+ Connect.create_application_user(user)
20
+ expect(Api::ApplicationUsersController.last_action).to eq :create
21
+ expect(Api::ApplicationUsersController.last_params).not_to be_nil
22
+ end
23
+ end
24
+ end
@@ -2,6 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  module OpenStax::Connect
4
4
  describe User do
5
- pending "add some examples to (or delete) #{__FILE__}"
5
+ it 'can return an AnonymousUser' do
6
+ anon = User.anonymous
7
+ expect(anon.is_anonymous?).to eq true
8
+ expect(anon.first_name).to eq 'Guest'
9
+ expect(anon.last_name).to eq 'User'
10
+ expect(anon.openstax_uid).to be_nil
11
+ end
6
12
  end
7
13
  end
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,13 @@
1
- # This file is copied to spec/ when you run 'rails generate rspec:install'
2
- ENV["RAILS_ENV"] ||= 'test'
3
- require File.expand_path("../../config/environment", __FILE__)
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require File.expand_path('../dummy/config/environment.rb', __FILE__)
4
4
  require 'rspec/rails'
5
5
  require 'rspec/autorun'
6
+ require 'factory_girl_rails'
6
7
 
7
8
  # Requires supporting ruby files with custom matchers and macros, etc,
9
+ Rails.backtrace_cleaner.remove_silencers!
10
+
8
11
  # in spec/support/ and its subdirectories.
9
12
  Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
10
13
 
@@ -18,7 +21,7 @@ RSpec.configure do |config|
18
21
  # config.mock_with :rr
19
22
 
20
23
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
21
- config.fixture_path = "#{::Rails.root}/spec/fixtures"
24
+ # config.fixture_path = "#{::Rails.root}/spec/fixtures"
22
25
 
23
26
  # If you're not using ActiveRecord, or you'd prefer not to run each of your
24
27
  # examples within a transaction, remove the following line or assign false
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstax_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-31 00:00:00.000000000 Z
12
+ date: 2014-04-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '3.1'
21
+ version: '3.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: '3.1'
29
+ version: '3.2'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: omniauth
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -59,6 +59,22 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.1'
62
+ - !ruby/object:Gem::Dependency
63
+ name: oauth2
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
62
78
  - !ruby/object:Gem::Dependency
63
79
  name: squeel
64
80
  requirement: !ruby/object:Gem::Requirement
@@ -171,6 +187,22 @@ dependencies:
171
187
  - - ! '>='
172
188
  - !ruby/object:Gem::Version
173
189
  version: '0'
190
+ - !ruby/object:Gem::Dependency
191
+ name: capybara
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ! '>='
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
174
206
  - !ruby/object:Gem::Dependency
175
207
  name: factory_girl_rails
176
208
  requirement: !ruby/object:Gem::Requirement
@@ -219,7 +251,7 @@ dependencies:
219
251
  - - ! '>='
220
252
  - !ruby/object:Gem::Version
221
253
  version: '0'
222
- description: Rails common code and bindings and for 'services' API
254
+ description: Rails common code and bindings and for 'accounts' API
223
255
  email:
224
256
  - jps@kindlinglabs.com
225
257
  executables: []
@@ -227,10 +259,8 @@ extensions: []
227
259
  extra_rdoc_files: []
228
260
  files:
229
261
  - app/assets/javascripts/openstax/connect/application.js
230
- - app/assets/javascripts/openstax/connect/sessions.js
231
262
  - app/assets/stylesheets/openstax/connect/application.css
232
263
  - app/assets/stylesheets/openstax/connect/dev.css.scss
233
- - app/assets/stylesheets/openstax/connect/sessions.css
234
264
  - app/controllers/openstax/connect/application_controller.rb
235
265
  - app/controllers/openstax/connect/dev/dev_controller.rb
236
266
  - app/controllers/openstax/connect/dev/users_controller.rb
@@ -238,7 +268,6 @@ files:
238
268
  - app/handlers/openstax/connect/dev/users_search.rb
239
269
  - app/handlers/openstax/connect/sessions_omniauth_authenticated.rb
240
270
  - app/helpers/openstax/connect/application_helper.rb
241
- - app/helpers/openstax/connect/sessions_helper.rb
242
271
  - app/models/openstax/connect/user.rb
243
272
  - app/routines/openstax/connect/dev/create_user.rb
244
273
  - app/routines/openstax/connect/search_users.rb
@@ -251,27 +280,58 @@ files:
251
280
  - app/views/openstax/connect/users/_action_list.html.erb
252
281
  - app/views/openstax/connect/users/_action_search.html.erb
253
282
  - app/views/openstax/connect/users/action_search.js.erb
254
- - config/initializers/01_requires.rb
255
- - config/initializers/02_extend_builtins.rb
283
+ - config/initializers/extend_builtins.rb
256
284
  - config/routes.rb
257
285
  - db/migrate/20130729213800_create_openstax_connect_users.rb
286
+ - db/migrate/20140410194004_add_fields_to_openstax_connect_users.rb
258
287
  - lib/omniauth/strategies/openstax.rb
259
288
  - lib/openstax/connect/action_list.rb
260
289
  - lib/openstax/connect/current_user_manager.rb
261
290
  - lib/openstax/connect/engine.rb
262
- - lib/openstax/connect/exceptions.rb
291
+ - lib/openstax/connect/inflections.rb
263
292
  - lib/openstax/connect/route_helper.rb
264
293
  - lib/openstax/connect/user_provider.rb
265
294
  - lib/openstax/connect/utilities.rb
266
295
  - lib/openstax/connect/version.rb
267
296
  - lib/openstax_connect.rb
268
- - lib/tasks/connect-rails_tasks.rake
269
297
  - spec/factories/openstax_connect_user.rb
270
298
  - MIT-LICENSE
271
299
  - Rakefile
272
300
  - README.md
301
+ - spec/controllers/openstax/connect/dev/users_controller_spec.rb
273
302
  - spec/controllers/openstax/connect/sessions_controller_spec.rb
274
- - spec/helpers/openstax/connect/sessions_helper_spec.rb
303
+ - spec/dummy/app/assets/javascripts/application.js
304
+ - spec/dummy/app/assets/stylesheets/application.css
305
+ - spec/dummy/app/controllers/api/application_users_controller.rb
306
+ - spec/dummy/app/controllers/api/dummy_controller.rb
307
+ - spec/dummy/app/controllers/application_controller.rb
308
+ - spec/dummy/app/helpers/application_helper.rb
309
+ - spec/dummy/config/application.rb
310
+ - spec/dummy/config/boot.rb
311
+ - spec/dummy/config/database.yml
312
+ - spec/dummy/config/environment.rb
313
+ - spec/dummy/config/environments/development.rb
314
+ - spec/dummy/config/environments/production.rb
315
+ - spec/dummy/config/environments/test.rb
316
+ - spec/dummy/config/initializers/backtrace_silencers.rb
317
+ - spec/dummy/config/initializers/inflections.rb
318
+ - spec/dummy/config/initializers/mime_types.rb
319
+ - spec/dummy/config/initializers/openstax_connect.rb
320
+ - spec/dummy/config/initializers/secret_token.rb
321
+ - spec/dummy/config/initializers/session_store.rb
322
+ - spec/dummy/config/initializers/wrap_parameters.rb
323
+ - spec/dummy/config/locales/en.yml
324
+ - spec/dummy/config/routes.rb
325
+ - spec/dummy/config.ru
326
+ - spec/dummy/db/schema.rb
327
+ - spec/dummy/public/404.html
328
+ - spec/dummy/public/422.html
329
+ - spec/dummy/public/500.html
330
+ - spec/dummy/public/favicon.ico
331
+ - spec/dummy/Rakefile
332
+ - spec/dummy/README.md
333
+ - spec/dummy/script/rails
334
+ - spec/lib/openstax_connect_spec.rb
275
335
  - spec/models/openstax/connect/user_spec.rb
276
336
  - spec/spec_helper.rb
277
337
  homepage: http://github.com/openstax/connect-rails
@@ -288,7 +348,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
288
348
  version: '0'
289
349
  segments:
290
350
  - 0
291
- hash: -2740690408514984727
351
+ hash: -2578089053068743772
292
352
  required_rubygems_version: !ruby/object:Gem::Requirement
293
353
  none: false
294
354
  requirements:
@@ -297,16 +357,48 @@ required_rubygems_version: !ruby/object:Gem::Requirement
297
357
  version: '0'
298
358
  segments:
299
359
  - 0
300
- hash: -2740690408514984727
360
+ hash: -2578089053068743772
301
361
  requirements: []
302
362
  rubyforge_project:
303
363
  rubygems_version: 1.8.25
304
364
  signing_key:
305
365
  specification_version: 3
306
- summary: Rails common code and bindings and for 'services' API
366
+ summary: Rails common code and bindings and for 'accounts' API
307
367
  test_files:
368
+ - spec/controllers/openstax/connect/dev/users_controller_spec.rb
308
369
  - spec/controllers/openstax/connect/sessions_controller_spec.rb
370
+ - spec/dummy/app/assets/javascripts/application.js
371
+ - spec/dummy/app/assets/stylesheets/application.css
372
+ - spec/dummy/app/controllers/api/application_users_controller.rb
373
+ - spec/dummy/app/controllers/api/dummy_controller.rb
374
+ - spec/dummy/app/controllers/application_controller.rb
375
+ - spec/dummy/app/helpers/application_helper.rb
376
+ - spec/dummy/config/application.rb
377
+ - spec/dummy/config/boot.rb
378
+ - spec/dummy/config/database.yml
379
+ - spec/dummy/config/environment.rb
380
+ - spec/dummy/config/environments/development.rb
381
+ - spec/dummy/config/environments/production.rb
382
+ - spec/dummy/config/environments/test.rb
383
+ - spec/dummy/config/initializers/backtrace_silencers.rb
384
+ - spec/dummy/config/initializers/inflections.rb
385
+ - spec/dummy/config/initializers/mime_types.rb
386
+ - spec/dummy/config/initializers/openstax_connect.rb
387
+ - spec/dummy/config/initializers/secret_token.rb
388
+ - spec/dummy/config/initializers/session_store.rb
389
+ - spec/dummy/config/initializers/wrap_parameters.rb
390
+ - spec/dummy/config/locales/en.yml
391
+ - spec/dummy/config/routes.rb
392
+ - spec/dummy/config.ru
393
+ - spec/dummy/db/schema.rb
394
+ - spec/dummy/public/404.html
395
+ - spec/dummy/public/422.html
396
+ - spec/dummy/public/500.html
397
+ - spec/dummy/public/favicon.ico
398
+ - spec/dummy/Rakefile
399
+ - spec/dummy/README.md
400
+ - spec/dummy/script/rails
309
401
  - spec/factories/openstax_connect_user.rb
310
- - spec/helpers/openstax/connect/sessions_helper_spec.rb
402
+ - spec/lib/openstax_connect_spec.rb
311
403
  - spec/models/openstax/connect/user_spec.rb
312
404
  - spec/spec_helper.rb