cookbook 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +10 -0
  5. data/Gemfile +39 -0
  6. data/Gemfile.lock +367 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +105 -0
  9. data/Rakefile +52 -0
  10. data/VERSION +1 -0
  11. data/app/assets/stylesheets/cookbook/application.scss +180 -0
  12. data/app/controllers/concerns/cookbook/params.rb +27 -0
  13. data/app/helpers/cookbook/application_helper.rb +38 -0
  14. data/app/models/cookbook/use.rb +26 -0
  15. data/app/views/cookbook/_fields.html.haml +11 -0
  16. data/app/views/cookbook/_used_in.html.haml +15 -0
  17. data/app/views/cookbook/_uses_of.html.haml +11 -0
  18. data/app/views/cookbook/uses/_fields.html.haml +17 -0
  19. data/bin/rails +16 -0
  20. data/config/initializers/simple_form.rb +180 -0
  21. data/config/locales/simple_form.en.yml +31 -0
  22. data/cookbook.gemspec +249 -0
  23. data/db/migrate/20210909141929_create_uses.cookbook.rb +21 -0
  24. data/lib/cookbook/configuration.rb +28 -0
  25. data/lib/cookbook/engine.rb +34 -0
  26. data/lib/cookbook/extensions/float.rb +10 -0
  27. data/lib/cookbook/mixins/acts_as_use_of.rb +45 -0
  28. data/lib/cookbook/mixins/acts_as_used_in.rb +43 -0
  29. data/lib/cookbook/railtie.rb +6 -0
  30. data/lib/cookbook/version.rb +9 -0
  31. data/lib/cookbook.rb +27 -0
  32. data/lib/tasks/cookbook_tasks.rake +5 -0
  33. data/lib/templates/haml/scaffold/_form.html.haml +12 -0
  34. data/spec/cookbook_spec.rb +9 -0
  35. data/spec/dummy/Rakefile +8 -0
  36. data/spec/dummy/app/assets/config/manifest.js +2 -0
  37. data/spec/dummy/app/assets/images/.keep +0 -0
  38. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  39. data/spec/dummy/app/assets/stylesheets/scaffolds.scss +65 -0
  40. data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
  41. data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
  42. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  43. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  44. data/spec/dummy/app/controllers/how_tos_controller.rb +61 -0
  45. data/spec/dummy/app/controllers/ingredients_controller.rb +60 -0
  46. data/spec/dummy/app/controllers/recipes_controller.rb +61 -0
  47. data/spec/dummy/app/controllers/supplies_controller.rb +60 -0
  48. data/spec/dummy/app/controllers/tools_controller.rb +60 -0
  49. data/spec/dummy/app/javascript/packs/application.js +16 -0
  50. data/spec/dummy/app/jobs/application_job.rb +9 -0
  51. data/spec/dummy/app/mailers/application_mailer.rb +6 -0
  52. data/spec/dummy/app/models/ability.rb +21 -0
  53. data/spec/dummy/app/models/application_record.rb +7 -0
  54. data/spec/dummy/app/models/concerns/.keep +0 -0
  55. data/spec/dummy/app/models/how_to.rb +5 -0
  56. data/spec/dummy/app/models/ingredient.rb +5 -0
  57. data/spec/dummy/app/models/recipe.rb +5 -0
  58. data/spec/dummy/app/models/supply.rb +5 -0
  59. data/spec/dummy/app/models/tool.rb +5 -0
  60. data/spec/dummy/app/models/user.rb +8 -0
  61. data/spec/dummy/app/views/how_tos/_form.html.haml +7 -0
  62. data/spec/dummy/app/views/how_tos/edit.html.haml +7 -0
  63. data/spec/dummy/app/views/how_tos/index.html.haml +25 -0
  64. data/spec/dummy/app/views/how_tos/new.html.haml +5 -0
  65. data/spec/dummy/app/views/how_tos/show.html.haml +17 -0
  66. data/spec/dummy/app/views/ingredients/_form.html.haml +8 -0
  67. data/spec/dummy/app/views/ingredients/edit.html.haml +7 -0
  68. data/spec/dummy/app/views/ingredients/index.html.haml +29 -0
  69. data/spec/dummy/app/views/ingredients/new.html.haml +5 -0
  70. data/spec/dummy/app/views/ingredients/show.html.haml +23 -0
  71. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  72. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  73. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  74. data/spec/dummy/app/views/recipes/_form.html.haml +9 -0
  75. data/spec/dummy/app/views/recipes/edit.html.haml +7 -0
  76. data/spec/dummy/app/views/recipes/index.html.haml +29 -0
  77. data/spec/dummy/app/views/recipes/new.html.haml +5 -0
  78. data/spec/dummy/app/views/recipes/show.html.haml +23 -0
  79. data/spec/dummy/app/views/supplies/_form.html.haml +6 -0
  80. data/spec/dummy/app/views/supplies/edit.html.haml +7 -0
  81. data/spec/dummy/app/views/supplies/index.html.haml +25 -0
  82. data/spec/dummy/app/views/supplies/new.html.haml +5 -0
  83. data/spec/dummy/app/views/supplies/show.html.haml +17 -0
  84. data/spec/dummy/app/views/tools/_form.html.haml +6 -0
  85. data/spec/dummy/app/views/tools/edit.html.haml +7 -0
  86. data/spec/dummy/app/views/tools/index.html.haml +25 -0
  87. data/spec/dummy/app/views/tools/new.html.haml +5 -0
  88. data/spec/dummy/app/views/tools/show.html.haml +17 -0
  89. data/spec/dummy/bin/rails +6 -0
  90. data/spec/dummy/bin/rake +6 -0
  91. data/spec/dummy/bin/setup +35 -0
  92. data/spec/dummy/config/application.rb +28 -0
  93. data/spec/dummy/config/boot.rb +7 -0
  94. data/spec/dummy/config/cable.yml +10 -0
  95. data/spec/dummy/config/database.yml +25 -0
  96. data/spec/dummy/config/environment.rb +7 -0
  97. data/spec/dummy/config/environments/development.rb +80 -0
  98. data/spec/dummy/config/environments/production.rb +122 -0
  99. data/spec/dummy/config/environments/test.rb +61 -0
  100. data/spec/dummy/config/initializers/application_controller_renderer.rb +9 -0
  101. data/spec/dummy/config/initializers/assets.rb +14 -0
  102. data/spec/dummy/config/initializers/backtrace_silencers.rb +10 -0
  103. data/spec/dummy/config/initializers/content_security_policy.rb +29 -0
  104. data/spec/dummy/config/initializers/cookbook.rb +6 -0
  105. data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
  106. data/spec/dummy/config/initializers/devise.rb +313 -0
  107. data/spec/dummy/config/initializers/filter_parameter_logging.rb +8 -0
  108. data/spec/dummy/config/initializers/inflections.rb +17 -0
  109. data/spec/dummy/config/initializers/json.rb +20 -0
  110. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  111. data/spec/dummy/config/initializers/permissions_policy.rb +12 -0
  112. data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
  113. data/spec/dummy/config/locales/devise.en.yml +65 -0
  114. data/spec/dummy/config/locales/en.yml +33 -0
  115. data/spec/dummy/config/puma.rb +45 -0
  116. data/spec/dummy/config/routes.rb +13 -0
  117. data/spec/dummy/config/storage.yml +34 -0
  118. data/spec/dummy/config.ru +8 -0
  119. data/spec/dummy/db/development.sqlite3 +0 -0
  120. data/spec/dummy/db/migrate/20210909175711_create_how_tos.rb +16 -0
  121. data/spec/dummy/db/migrate/20210909181442_create_ingredients.rb +16 -0
  122. data/spec/dummy/db/migrate/20210909181455_create_supplies.rb +14 -0
  123. data/spec/dummy/db/migrate/20210909181516_create_tools.rb +14 -0
  124. data/spec/dummy/db/migrate/20210909181533_create_recipes.rb +16 -0
  125. data/spec/dummy/db/migrate/20210909185303_create_uses.cookbook.rb +23 -0
  126. data/spec/dummy/db/migrate/20210910142322_create_users.rb +11 -0
  127. data/spec/dummy/db/migrate/20210910142323_add_devise_to_users.rb +50 -0
  128. data/spec/dummy/db/schema.rb +92 -0
  129. data/spec/dummy/db/seeds.rb +10 -0
  130. data/spec/dummy/db/test.sqlite3 +0 -0
  131. data/spec/dummy/lib/assets/.keep +0 -0
  132. data/spec/dummy/lib/templates/haml/scaffold/_form.html.haml +6 -0
  133. data/spec/dummy/log/.keep +0 -0
  134. data/spec/dummy/log/development.log +6643 -0
  135. data/spec/dummy/log/test.log +25990 -0
  136. data/spec/dummy/public/404.html +67 -0
  137. data/spec/dummy/public/422.html +67 -0
  138. data/spec/dummy/public/500.html +66 -0
  139. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  140. data/spec/dummy/public/apple-touch-icon.png +0 -0
  141. data/spec/dummy/public/favicon.ico +0 -0
  142. data/spec/dummy/storage/.keep +0 -0
  143. data/spec/factories/how_tos.rb +9 -0
  144. data/spec/factories/ingredients.rb +11 -0
  145. data/spec/factories/recipes.rb +11 -0
  146. data/spec/factories/supplies.rb +9 -0
  147. data/spec/factories/tools.rb +9 -0
  148. data/spec/factories/users.rb +9 -0
  149. data/spec/factories/uses.rb +24 -0
  150. data/spec/helpers/cookbook/application_helper_spec.rb +47 -0
  151. data/spec/models/cookbook/use_spec.rb +82 -0
  152. data/spec/models/how_to_spec.rb +18 -0
  153. data/spec/models/ingredient_spec.rb +15 -0
  154. data/spec/models/recipe_spec.rb +18 -0
  155. data/spec/models/supply_spec.rb +15 -0
  156. data/spec/models/tool_spec.rb +15 -0
  157. data/spec/rails_helper.rb +92 -0
  158. data/spec/requests/how_tos_spec.rb +114 -0
  159. data/spec/requests/recipes_spec.rb +116 -0
  160. data/spec/spec_helper.rb +44 -0
  161. metadata +517 -0
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # Works Cited
2
+ Works Cited allows you to add a list of the works cited in ActiveRecord objects, to be formatted by a helper that can be added to relevant pages to format the citations like a bibliography.
3
+
4
+ Works Cited uses CanCanCan to authorize the editing of citations. This makes it easy for you to control access.
5
+
6
+ ## Installation
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'works_cited'
11
+ ```
12
+
13
+ And then execute:
14
+ ```bash
15
+ $ bundle install
16
+ ```
17
+
18
+ Then generate the migrations
19
+ ```bash
20
+ $ rake cookbook:install:migrations
21
+ $ rake db:migrate
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ You will need to add access for the people who should be authorized. Cookbook uses CanCanCan for authorization. Simply add the appropriate permissions to your ability.rb file:
27
+
28
+ ```ruby
29
+ class Ability
30
+ include CanCan::Ability
31
+
32
+ def initialize(user)
33
+ user ||= User.new
34
+
35
+ can :read, Cookbook::Use
36
+ can :read, Recipe
37
+ can :read, Ingredient
38
+
39
+ return if user.new_record? # Anonymous Users leave
40
+
41
+ # # We could have other rules in here, like:
42
+ # can :manage, Cookbook::Use, use_of: { user_id: user.id }, use_in: { user_id: user.id }
43
+
44
+ return unless user.admin? # Non Admin Users leave
45
+
46
+ can :manage, Cookbook::Use
47
+ can :manage, Recipe
48
+ can :manage, Ingredient
49
+ end
50
+ end
51
+ ```
52
+
53
+ ## Usage
54
+ Make a model ready to accept uses, such as Recipe or Instructions
55
+
56
+ ```ruby
57
+ acts_as_use_of
58
+ ```
59
+
60
+ Make a model a thing that gets used, such as Ingredient or Tool
61
+
62
+ ```ruby
63
+ acts_as_used_in
64
+ ```
65
+
66
+ Add the helpers to the relevant views
67
+
68
+ ```haml
69
+ = cookbook_uses_of @ingredient
70
+ -# OR
71
+ = cookbook_used_in @recipe
72
+ ```
73
+
74
+ Add the fields to your instructional forms (e.g. Recipes)
75
+
76
+ ```haml
77
+ = form_for(@recipe) do |f|
78
+ = cookbook_fields f
79
+ ```
80
+
81
+ Don't forget to add the controller concern to enable nested attributes with strong parameters
82
+
83
+ ```ruby
84
+ class RecipesController < ApplicationController
85
+ include Cookbook::Params
86
+
87
+ #...
88
+
89
+ def recipe_params
90
+ params.require(:recipe).permit(:name, :description, :serves, :meal, :instructions, cookbook_params('Recipe'))
91
+ end
92
+ end
93
+ ```
94
+
95
+ ## Contributing
96
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
97
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
98
+ * Fork the project.
99
+ * Start a feature/bugfix branch.
100
+ * Commit and push until you are happy with your contribution.
101
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
102
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
103
+
104
+ ## License
105
+ Copyright (c) 2021 Loren Lundgren. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ warn e.message
9
+ warn 'Run `bundle install` to install missing gems'
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+ require 'juwelier'
14
+ Juwelier::Tasks.new do |gem|
15
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
16
+ gem.name = 'cookbook'
17
+ gem.homepage = 'https://gemvein.com/museum/cases/cookbook'
18
+ gem.metadata = { source_code_uri: 'http://github.com/gemvein/cookbook' }
19
+ gem.license = 'MIT'
20
+ gem.summary = %(Mountable Engine to show instructions with components, like a cookbook or instruction manual)
21
+ gem.description = 'Cookbook allows you to associate instructions with components in a cross referenced way. '\
22
+ 'Good for cooking recipes or an instruction manual for DIY projects.'
23
+ gem.email = 'loren.lundgren@gmail.com'
24
+ gem.authors = ['Loren Lundgren']
25
+
26
+ # dependencies defined in Gemfile
27
+ end
28
+ Juwelier::RubygemsDotOrgTasks.new
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ desc 'Code coverage detail'
37
+ task :simplecov do
38
+ ENV['COVERAGE'] = 'true'
39
+ Rake::Task['test'].execute
40
+ end
41
+
42
+ task default: :test
43
+
44
+ require 'rdoc/task'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "cookbook #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,180 @@
1
+ $danger-color: darkred;
2
+
3
+ $button-color: darkgray;
4
+ $button-text-color: white;
5
+ $button-link-color: darkslateblue;
6
+ $button-link-text-color: white;
7
+ $button-action-color: darkolivegreen;
8
+ $button-action-text-color: white;
9
+ $button-danger-color: darkred;
10
+ $button-danger-text-color: white;
11
+
12
+ $table-border-color: darkgray;
13
+ $fieldset-border-color: darkgray;
14
+ $hr-border-color: darkgray;
15
+
16
+ $shadow-color: rgba(darkgray, 0.5);
17
+
18
+ .button, button, input[type=button], input[type=submit], .item-actions li a {
19
+ background: $button-color;
20
+ color: $button-text-color;
21
+ padding: 0.5rem 1.25rem;
22
+ border-radius: 0.33rem;
23
+ border: 1px lighten($button-color, 20%) outset;
24
+ box-shadow: 2px 2px 2px $shadow-color;
25
+ display: inline-block;
26
+
27
+ &:active {
28
+ border-style: inset;
29
+ box-shadow: 1px 1px 2px rgba($shadow-color, 0.5);
30
+ }
31
+
32
+ &.button-link {
33
+ background-color: $button-link-color;
34
+ border-color: lighten($button-link-color, 20%);
35
+ color: $button-link-text-color;
36
+
37
+ &:active {
38
+ background: darken($button-link-color, 20%);
39
+ }
40
+ }
41
+
42
+ &.button-action {
43
+ background-color: $button-action-color;
44
+ border-color: lighten($button-action-color, 20%);
45
+ color: $button-action-text-color;
46
+
47
+ &:active {
48
+ background: darken($button-action-color, 20%);
49
+ }
50
+ }
51
+
52
+ &.button-danger {
53
+ background-color: $button-danger-color;
54
+ border-color: lighten($button-danger-color, 10%);
55
+ color: $button-danger-text-color;
56
+
57
+ &:active {
58
+ background: darken($button-danger-color, 20%);
59
+ }
60
+ }
61
+
62
+ &.button-large {
63
+ font-size: 1.5rem;
64
+ }
65
+
66
+ &:active,
67
+ &:visited,
68
+ &:link,
69
+ &:hover {
70
+ text-decoration: none;
71
+ }
72
+
73
+ &.button-block {
74
+ display: block;
75
+ text-align: center;
76
+ }
77
+ }
78
+
79
+ table.table-data {
80
+ border-collapse: collapse;
81
+ border: solid 1px $table-border-color;
82
+
83
+ td, th {
84
+ border: solid 1px $table-border-color;
85
+ padding: 0.5rem;
86
+ }
87
+ }
88
+
89
+ .error {
90
+ font-weight: bold;
91
+ color: $danger-color;
92
+ }
93
+
94
+ .field_with_errors input, .field_with_errors select, .field_with_errors textarea {
95
+ border: 1px solid $danger-color;
96
+ box-shadow: 1px 1px 4px $danger-color;
97
+ }
98
+
99
+ .required abbr[title=required] {
100
+ font-weight: bold;
101
+ color: $danger-color;
102
+ }
103
+
104
+ .input, .actions {
105
+ display: grid;
106
+ grid-template-columns: 15rem 2fr 1fr;
107
+ grid-gap: 0.5rem;
108
+ margin-bottom: 0.5rem;
109
+
110
+ @media (max-width: 60rem) {
111
+ grid-template-columns: 10rem 1fr;
112
+ }
113
+
114
+ &.input-sort input {
115
+ width: 3rem;
116
+ }
117
+
118
+ label {
119
+ text-align: right;
120
+ }
121
+
122
+ input[type=text],
123
+ input[type=number],
124
+ input[type=password],
125
+ input[type=url],
126
+ input[type=email],
127
+ select,
128
+ textarea {
129
+ padding: 0.5rem;
130
+ font-size: 1.25rem;
131
+ }
132
+
133
+ input[type=text],
134
+ input[type=number],
135
+ input[type=password],
136
+ input[type=url],
137
+ input[type=email] {
138
+ height: 1.5rem;
139
+ }
140
+ }
141
+
142
+ label.checkbox {
143
+ display: flex;
144
+ justify-content: flex-start;
145
+ grid-column-start: 2;
146
+ }
147
+
148
+ .button-wrapper {
149
+ display: flex;
150
+ justify-content: flex-end;
151
+ grid-column-start: 2;
152
+ }
153
+
154
+ .radio-wrapper, .checkbox-wrapper {
155
+ display: grid;
156
+ grid-template-columns: 1rem 1fr;
157
+ grid-column-gap: 0.5rem;
158
+
159
+ label {
160
+ text-align: left;
161
+ }
162
+ }
163
+
164
+ textarea {
165
+ padding: 0.5rem;
166
+ }
167
+
168
+ fieldset {
169
+ border: solid 1px $fieldset-border-color;
170
+ margin: 1rem 10rem;
171
+
172
+ fieldset {
173
+ margin: 0 5rem;
174
+ }
175
+ }
176
+
177
+ .preview-html {
178
+ font-size: 1.2rem;
179
+ line-height: 1.5rem;
180
+ }
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cookbook
4
+ # Concern to allow strong parameters when using accepts_nested_attributes_for to edit Cookbook Uses
5
+ module Params
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ # rescue_from Pundit::NotAuthorizedError, with: :authorization_error
10
+ # include Pundit
11
+ end
12
+
13
+ def cookbook_params(model_name)
14
+ model = model_name.constantize
15
+
16
+ attributes = {}
17
+ model.used_in.each do |table_sym|
18
+ singular = table_sym.to_s.singularize
19
+ attribute_sym = "#{singular}_uses_attributes".to_sym
20
+ attributes[attribute_sym] = %i[
21
+ id _destroy use_of_type use_of_id quantity_minimum quantity_maximum unit preparation note sort
22
+ ]
23
+ end
24
+ attributes
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cookbook
4
+ # Application Helper
5
+ module ApplicationHelper
6
+ def cookbook_uses_of(usable)
7
+ render 'cookbook/uses_of', uses: usable.uses
8
+ end
9
+
10
+ def cookbook_used_in(using)
11
+ render 'cookbook/used_in', usables: build_usables(using)
12
+ end
13
+
14
+ def cookbook_fields(form)
15
+ render 'cookbook/fields', form: form, usables: build_usables(form.object)
16
+ end
17
+
18
+ private
19
+
20
+ def build_usables(object)
21
+ object.class.used_in.map do |usable_table_sym|
22
+ build_usable(object, usable_table_sym)
23
+ end
24
+ end
25
+
26
+ def build_usable(object, usable_table_sym)
27
+ plural = usable_table_sym.to_s
28
+ singular = plural.singularize
29
+ uses_sym = "#{singular}_uses".to_sym
30
+ usable_model = plural.classify.constantize
31
+ singular_title = usable_model.model_name.human
32
+ OpenStruct.new(
33
+ title: singular_title.pluralize, singular_title: singular_title, uses: object.send(uses_sym),
34
+ uses_sym: uses_sym, plural_class: plural, singular_class: singular, table_sym: usable_table_sym
35
+ )
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cookbook
4
+ # Cookbook::Use is basically a linking table with extra information.
5
+ class Use < ApplicationRecord
6
+ # Relationships
7
+ belongs_to :use_in, polymorphic: true
8
+ belongs_to :use_of, polymorphic: true
9
+
10
+ # Scopes
11
+ scope :recipe_uses, -> { where use_in_type: 'Recipe' }
12
+ scope :ingredient_uses, -> { where use_of_type: 'Ingredient' }
13
+
14
+ # Methods
15
+ def quantity_with_unit
16
+ [quantity, unit].compact.join(' ')
17
+ end
18
+
19
+ def quantity
20
+ min = quantity_minimum&.format_quantity
21
+ max = quantity_maximum&.format_quantity
22
+
23
+ [min, max].compact.join('–') # ndash, not hyphen
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ = javascript_include_tag 'vanilla_nested'
2
+ - if Cookbook.configuration.include_cookbook_css == true
3
+ = stylesheet_link_tag 'cookbook/application'
4
+ - usables.each do |usable|
5
+ %fieldset.used_in{class: usable.plural_class}
6
+ %legend
7
+ %h3= usable.title
8
+ = link_to_add_nested form, usable.uses_sym, "##{usable.plural_class}", partial: 'cookbook/uses/fields', link_text: "Add #{usable.singular_title}", link_classes: 'button button-action'
9
+ %div{id: usable.plural_class}
10
+ = form.fields_for usable.uses_sym do |g|
11
+ = render 'cookbook/uses/fields', form: g, usable: usable