strong_form 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AGPL-LICENSE +661 -0
- data/Rakefile +28 -0
- data/lib/strong_form.rb +5 -0
- data/lib/strong_form/finder.rb +16 -0
- data/lib/strong_form/form.rb +56 -0
- data/lib/strong_form/nested_form.rb +38 -0
- data/lib/strong_form/railtie.rb +31 -0
- data/lib/strong_form/record.rb +16 -0
- data/lib/strong_form/tag.rb +12 -0
- data/lib/strong_form/version.rb +3 -0
- data/lib/tasks/strong_form_tasks.rake +4 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/base_controller.rb +22 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/address.rb +6 -0
- data/spec/dummy/app/models/tag.rb +3 -0
- data/spec/dummy/app/models/user.rb +7 -0
- data/spec/dummy/app/views/base/_address_fields.html.haml +10 -0
- data/spec/dummy/app/views/base/_tag_fields.html.haml +2 -0
- data/spec/dummy/app/views/base/_user_fields.html.haml +4 -0
- data/spec/dummy/app/views/base/basic_form.html.haml +2 -0
- data/spec/dummy/app/views/base/deep_fields_for.html.haml +8 -0
- data/spec/dummy/app/views/base/fields_for.html.haml +8 -0
- data/spec/dummy/app/views/base/nested_form_gem.html.haml +7 -0
- data/spec/dummy/app/views/layouts/application.html.haml +10 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +27 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +57 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20150626095843_create_users.rb +12 -0
- data/spec/dummy/db/migrate/20150626104120_create_addresses.rb +13 -0
- data/spec/dummy/db/migrate/20150626132542_create_tags.rb +11 -0
- data/spec/dummy/db/schema.rb +44 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +55 -0
- data/spec/dummy/log/test.log +13928 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/2LhrvKfMxngd4BdL-T9u1PoK7r2yCrsF0F7Kfd3Ah_E.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/51piSq8D_vSYzuo29rqbhXeezoY2DCrHKutZ4oxBHhg.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/5G4z0ygg3o4YrC8hdVviqeaSPwFizCPEz9C_aP3xEf4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/6HZK27_4B_5JmRqd-_qY4A4hlMpkUhe5T2NBYDBhhtY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/7ujPiNFNHPEE5v8dU7pWT1mFTAIzzANjE_WnhuOn5aQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/BzvE8UQ9KacHmD--VP941KFQNmtCCtrawpZ0I-RiJ_I.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/D2r9R9v7HN8bhcRxAk9Fq198KPyRMlGc6pTeXk7akFY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/K_5SG-ud7IMx-4BeZy5hmsicHUiqJlF0tZQjyR3NNEU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/QEdR93qQ7nm2SXxevYI5Jq-kZ1bMKqprrz_1CIog8cY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/SJbwTdB2TakRdPR0nH-X3xfT67Q2hf09i_4vNn90Ntw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/_yOk6c3S7xX6EByWm0rTZ3-h6G5R-0Ge65s1mE62K6A.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/e7M8G17FmxSeoA5Hsf5--bxNsxEVKc7QeyJ0xpag8Dk.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/eFzh__t_QtfMtE7gJNX9lWmkNGR1gwr-qeBFKqaapzE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/eOkP0DI4t_W9XXjhMLYN1h9XQHVX47uYT5mxUaf5d8c.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/fCdygUQVvilffWkcrZOOmWAmg7_SGBAllsGphcjPUgI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/h46aLbOd8j7U9bu77JY1Q_My7hoRoFram5quuS5mTNY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/mdlk4FrQ_MAYAufc3sZP3Womvzc2ygzcE3wI8h-HtG8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/nFFtnxQpd52C5Kw2pAiHS8UAeTmmHYy1bKqAvX9URXg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/o5l8KQJq6xdUXyLhmo54-Hq3b4IBPiejD7IVebnzsfg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/qzaJT3HFRBZRH91xzxTdWOj3bMvepjEc7g8K9lDSq2E.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/ugAO4WRjF1KW12RW1b9zwLT8jfn5FBDPuO3cPg3ETKM.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/xRuy4fW0E5CWWpAMIAzcxNKri0l5BRWXNdikJDAGbZc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/xm4K2DO5jy_tnB04EtEXjdEZC3rMAvHvZGHmpC4tFeQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/yy6a1dwFUwRlNVthC-5nAYk3ICpfyp79q5qfO0FHibQ.cache +1 -0
- data/spec/examples.txt +52 -0
- data/spec/features/strong_form_spec.rb +338 -0
- data/spec/models/user_spec.rb +46 -0
- data/spec/rails_helper.rb +53 -0
- data/spec/spec_helper.rb +92 -0
- metadata +317 -0
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'StrongForm'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
Bundler::GemHelper.install_tasks
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'lib'
|
23
|
+
t.libs << 'test'
|
24
|
+
t.pattern = 'test/**/*_test.rb'
|
25
|
+
t.verbose = false
|
26
|
+
end
|
27
|
+
|
28
|
+
task default: :test
|
data/lib/strong_form.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module StrongForm
|
2
|
+
module Finder
|
3
|
+
def self.find_child_permitted_attributes(name, permitted_attributes)
|
4
|
+
# find the hash with the key `child_models_attributes`
|
5
|
+
attributes = permitted_attributes.find do |o|
|
6
|
+
o.is_a?(Hash) && o.keys.include?(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
return [] unless attributes
|
10
|
+
|
11
|
+
attributes = attributes[name]
|
12
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
13
|
+
attributes
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ActionView
|
2
|
+
module Helpers
|
3
|
+
module FormHelper
|
4
|
+
alias_method :orig_form_for, :form_for
|
5
|
+
|
6
|
+
attr_accessor :permitted_attributes
|
7
|
+
|
8
|
+
def form_for(record, options = {}, &block)
|
9
|
+
# explicilty passed
|
10
|
+
if options.key?(:permitted_attributes)
|
11
|
+
self.permitted_attributes = options.delete(:permitted_attributes)
|
12
|
+
record.permitted_attributes =
|
13
|
+
permitted_attributes if record.respond_to?(:permitted_attributes=)
|
14
|
+
# assigned to object
|
15
|
+
elsif record.respond_to?(:permitted_attributes)
|
16
|
+
self.permitted_attributes = record.permitted_attributes
|
17
|
+
end
|
18
|
+
|
19
|
+
orig_form_for(record, options, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def assign_child_permitted_attributes!(
|
23
|
+
record_name, record_object, parent_permitted_attributes
|
24
|
+
)
|
25
|
+
if parent_permitted_attributes == true # parent allowed everything
|
26
|
+
record_object.permitted_attributes = parent_permitted_attributes
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
# search for nested attributes
|
31
|
+
|
32
|
+
# record_name is of the form `user[child_models_attributes][0]`
|
33
|
+
# try to extract `child_models_attributes`
|
34
|
+
permitted_name =
|
35
|
+
record_name.match(/.*?\[([^\]\[]+)\](\[[0-9]+\])?$/)[1].to_sym
|
36
|
+
|
37
|
+
# find the hash with the key `child_models_attributes`
|
38
|
+
record_object.permitted_attributes =
|
39
|
+
StrongForm::Finder.find_child_permitted_attributes(
|
40
|
+
permitted_name, parent_permitted_attributes
|
41
|
+
)
|
42
|
+
end
|
43
|
+
private :assign_child_permitted_attributes!
|
44
|
+
|
45
|
+
# https://github.com/rails/rails/blob/4-2-stable/actionview/lib/action_view/helpers/form_helper.rb#L712
|
46
|
+
def fields_for(record_name, record_object = nil, options = {}, &block)
|
47
|
+
assign_child_permitted_attributes!(
|
48
|
+
record_name, record_object, options[:parent_builder].object.permitted_attributes
|
49
|
+
) if permitted_attributes && record_object.respond_to?(:permitted_attributes=) && record_object.permitted_attributes.nil?
|
50
|
+
|
51
|
+
builder = instantiate_builder(record_name, record_object, options)
|
52
|
+
capture(builder, &block)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module NestedForm
|
2
|
+
module BuilderMixin
|
3
|
+
alias_method :orig_link_to_add, :link_to_add
|
4
|
+
alias_method :orig_link_to_remove, :link_to_remove
|
5
|
+
|
6
|
+
def link_to_add(association, options = {}, &block)
|
7
|
+
if object.respond_to?(:permitted_attributes)
|
8
|
+
return unless object.permitted_nested_attributes?(association)
|
9
|
+
|
10
|
+
unless options[:model_object]
|
11
|
+
reflection = object.class.reflect_on_association(association)
|
12
|
+
options[:model_object] = reflection.klass.new
|
13
|
+
end
|
14
|
+
|
15
|
+
unless options[:model_object].permitted_attributes.present?
|
16
|
+
if object.permitted_attributes == true || object.permitted_attributes.nil?
|
17
|
+
options[:model_object].permitted_attributes = true
|
18
|
+
else
|
19
|
+
options[:model_object].permitted_attributes =
|
20
|
+
StrongForm::Finder.find_child_permitted_attributes(
|
21
|
+
"#{association}_attributes".to_sym, object.permitted_attributes
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
orig_link_to_add(association, options, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def link_to_remove(*args, &block)
|
31
|
+
return if object.respond_to?(:permitted_attributes) &&
|
32
|
+
!object.permitted_attributes.nil? &&
|
33
|
+
object.permitted_attributes != true &&
|
34
|
+
!object.permitted_attributes.include?(:_destroy)
|
35
|
+
orig_link_to_remove(*args, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module StrongForm
|
2
|
+
def self.inject
|
3
|
+
ActiveRecord::Base.include StrongForm::Record
|
4
|
+
|
5
|
+
%w(
|
6
|
+
CheckBox
|
7
|
+
CollectionSelect
|
8
|
+
DateSelect
|
9
|
+
RadioButton
|
10
|
+
Select
|
11
|
+
TextArea
|
12
|
+
TextField
|
13
|
+
TimeZoneSelect
|
14
|
+
).each do |klass|
|
15
|
+
"ActionView::Helpers::Tags::#{klass}"
|
16
|
+
.constantize.prepend StrongForm::Tag
|
17
|
+
end
|
18
|
+
|
19
|
+
defined?(NestedForm) && require('strong_form/nested_form')
|
20
|
+
end
|
21
|
+
|
22
|
+
class Railtie < Rails::Railtie
|
23
|
+
initializer 'strong_form.injects' do
|
24
|
+
if !Rails.env.test? && Rails.configuration.cache_classes
|
25
|
+
StrongForm.inject
|
26
|
+
else
|
27
|
+
ActionDispatch::Reloader.to_prepare { StrongForm.inject }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module StrongForm
|
2
|
+
module Record
|
3
|
+
attr_accessor :permitted_attributes
|
4
|
+
|
5
|
+
# allows to check if nested attributes are allowed
|
6
|
+
#
|
7
|
+
# permitted_nested_attributes?(:addresses) is true if
|
8
|
+
# :addresses_attributes are permitted or everything is permitted
|
9
|
+
def permitted_nested_attributes?(attr)
|
10
|
+
permitted_attributes.nil? || permitted_attributes == true ||
|
11
|
+
permitted_attributes.any? do |o|
|
12
|
+
o.is_a?(Hash) && o.keys.include?("#{attr}_attributes".to_sym)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module StrongForm
|
2
|
+
module Tag
|
3
|
+
def render
|
4
|
+
if object.respond_to?(:permitted_attributes) && !object.permitted_attributes.nil?
|
5
|
+
(@html_options || @options)[:disabled] ||=
|
6
|
+
object.permitted_attributes != true &&
|
7
|
+
!object.permitted_attributes.include?(@method_name.to_sym)
|
8
|
+
end
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class BaseController < ApplicationController
|
2
|
+
def basic_form
|
3
|
+
@user = User.new
|
4
|
+
end
|
5
|
+
|
6
|
+
def fields_for
|
7
|
+
@user = User.new
|
8
|
+
@user.addresses.build
|
9
|
+
@user.build_tag
|
10
|
+
end
|
11
|
+
|
12
|
+
def deep_fields_for
|
13
|
+
@user = User.new
|
14
|
+
(@user.addresses.build).tags.build
|
15
|
+
@user.build_tag
|
16
|
+
end
|
17
|
+
|
18
|
+
def nested_form_gem
|
19
|
+
@user = User.new
|
20
|
+
@user.addresses.build
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
|
5
|
+
%title Dummy
|
6
|
+
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
|
7
|
+
= javascript_include_tag 'application', 'data-turbolinks-track' => true
|
8
|
+
= csrf_meta_tags
|
9
|
+
%body
|
10
|
+
= yield
|
data/spec/dummy/bin/rake
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
# path to your application root.
|
5
|
+
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
|
6
|
+
|
7
|
+
Dir.chdir APP_ROOT do
|
8
|
+
# This script is a starting point to setup your application.
|
9
|
+
# Add necessary setup steps to this file:
|
10
|
+
|
11
|
+
puts '== Installing dependencies =='
|
12
|
+
system 'gem install bundler --conservative'
|
13
|
+
system 'bundle check || bundle install'
|
14
|
+
|
15
|
+
# puts "\n== Copying sample files =="
|
16
|
+
# unless File.exist?("config/database.yml")
|
17
|
+
# system "cp config/database.yml.sample config/database.yml"
|
18
|
+
# end
|
19
|
+
|
20
|
+
puts "\n== Preparing database =="
|
21
|
+
system 'bin/rake db:setup'
|
22
|
+
|
23
|
+
puts "\n== Removing old logs and tempfiles =="
|
24
|
+
system 'rm -f log/*'
|
25
|
+
system 'rm -rf tmp/cache'
|
26
|
+
|
27
|
+
puts "\n== Restarting application server =="
|
28
|
+
system 'touch tmp/restart.txt'
|
29
|
+
end
|