cookbook 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/.rubocop.yml +10 -0
- data/Gemfile +39 -0
- data/Gemfile.lock +367 -0
- data/LICENSE.txt +20 -0
- data/README.md +105 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/app/assets/stylesheets/cookbook/application.scss +180 -0
- data/app/controllers/concerns/cookbook/params.rb +27 -0
- data/app/helpers/cookbook/application_helper.rb +38 -0
- data/app/models/cookbook/use.rb +26 -0
- data/app/views/cookbook/_fields.html.haml +11 -0
- data/app/views/cookbook/_used_in.html.haml +15 -0
- data/app/views/cookbook/_uses_of.html.haml +11 -0
- data/app/views/cookbook/uses/_fields.html.haml +17 -0
- data/bin/rails +16 -0
- data/config/initializers/simple_form.rb +180 -0
- data/config/locales/simple_form.en.yml +31 -0
- data/cookbook.gemspec +249 -0
- data/db/migrate/20210909141929_create_uses.cookbook.rb +21 -0
- data/lib/cookbook/configuration.rb +28 -0
- data/lib/cookbook/engine.rb +34 -0
- data/lib/cookbook/extensions/float.rb +10 -0
- data/lib/cookbook/mixins/acts_as_use_of.rb +45 -0
- data/lib/cookbook/mixins/acts_as_used_in.rb +43 -0
- data/lib/cookbook/railtie.rb +6 -0
- data/lib/cookbook/version.rb +9 -0
- data/lib/cookbook.rb +27 -0
- data/lib/tasks/cookbook_tasks.rake +5 -0
- data/lib/templates/haml/scaffold/_form.html.haml +12 -0
- data/spec/cookbook_spec.rb +9 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/assets/stylesheets/scaffolds.scss +65 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
- data/spec/dummy/app/controllers/application_controller.rb +4 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/how_tos_controller.rb +61 -0
- data/spec/dummy/app/controllers/ingredients_controller.rb +60 -0
- data/spec/dummy/app/controllers/recipes_controller.rb +61 -0
- data/spec/dummy/app/controllers/supplies_controller.rb +60 -0
- data/spec/dummy/app/controllers/tools_controller.rb +60 -0
- data/spec/dummy/app/javascript/packs/application.js +16 -0
- data/spec/dummy/app/jobs/application_job.rb +9 -0
- data/spec/dummy/app/mailers/application_mailer.rb +6 -0
- data/spec/dummy/app/models/ability.rb +21 -0
- data/spec/dummy/app/models/application_record.rb +7 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/how_to.rb +5 -0
- data/spec/dummy/app/models/ingredient.rb +5 -0
- data/spec/dummy/app/models/recipe.rb +5 -0
- data/spec/dummy/app/models/supply.rb +5 -0
- data/spec/dummy/app/models/tool.rb +5 -0
- data/spec/dummy/app/models/user.rb +8 -0
- data/spec/dummy/app/views/how_tos/_form.html.haml +7 -0
- data/spec/dummy/app/views/how_tos/edit.html.haml +7 -0
- data/spec/dummy/app/views/how_tos/index.html.haml +25 -0
- data/spec/dummy/app/views/how_tos/new.html.haml +5 -0
- data/spec/dummy/app/views/how_tos/show.html.haml +17 -0
- data/spec/dummy/app/views/ingredients/_form.html.haml +8 -0
- data/spec/dummy/app/views/ingredients/edit.html.haml +7 -0
- data/spec/dummy/app/views/ingredients/index.html.haml +29 -0
- data/spec/dummy/app/views/ingredients/new.html.haml +5 -0
- data/spec/dummy/app/views/ingredients/show.html.haml +23 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/app/views/recipes/_form.html.haml +9 -0
- data/spec/dummy/app/views/recipes/edit.html.haml +7 -0
- data/spec/dummy/app/views/recipes/index.html.haml +29 -0
- data/spec/dummy/app/views/recipes/new.html.haml +5 -0
- data/spec/dummy/app/views/recipes/show.html.haml +23 -0
- data/spec/dummy/app/views/supplies/_form.html.haml +6 -0
- data/spec/dummy/app/views/supplies/edit.html.haml +7 -0
- data/spec/dummy/app/views/supplies/index.html.haml +25 -0
- data/spec/dummy/app/views/supplies/new.html.haml +5 -0
- data/spec/dummy/app/views/supplies/show.html.haml +17 -0
- data/spec/dummy/app/views/tools/_form.html.haml +6 -0
- data/spec/dummy/app/views/tools/edit.html.haml +7 -0
- data/spec/dummy/app/views/tools/index.html.haml +25 -0
- data/spec/dummy/app/views/tools/new.html.haml +5 -0
- data/spec/dummy/app/views/tools/show.html.haml +17 -0
- data/spec/dummy/bin/rails +6 -0
- data/spec/dummy/bin/rake +6 -0
- data/spec/dummy/bin/setup +35 -0
- data/spec/dummy/config/application.rb +28 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +80 -0
- data/spec/dummy/config/environments/production.rb +122 -0
- data/spec/dummy/config/environments/test.rb +61 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +9 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +10 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +29 -0
- data/spec/dummy/config/initializers/cookbook.rb +6 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
- data/spec/dummy/config/initializers/devise.rb +313 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +8 -0
- data/spec/dummy/config/initializers/inflections.rb +17 -0
- data/spec/dummy/config/initializers/json.rb +20 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/permissions_policy.rb +12 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
- data/spec/dummy/config/locales/devise.en.yml +65 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +45 -0
- data/spec/dummy/config/routes.rb +13 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/config.ru +8 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20210909175711_create_how_tos.rb +16 -0
- data/spec/dummy/db/migrate/20210909181442_create_ingredients.rb +16 -0
- data/spec/dummy/db/migrate/20210909181455_create_supplies.rb +14 -0
- data/spec/dummy/db/migrate/20210909181516_create_tools.rb +14 -0
- data/spec/dummy/db/migrate/20210909181533_create_recipes.rb +16 -0
- data/spec/dummy/db/migrate/20210909185303_create_uses.cookbook.rb +23 -0
- data/spec/dummy/db/migrate/20210910142322_create_users.rb +11 -0
- data/spec/dummy/db/migrate/20210910142323_add_devise_to_users.rb +50 -0
- data/spec/dummy/db/schema.rb +92 -0
- data/spec/dummy/db/seeds.rb +10 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/lib/templates/haml/scaffold/_form.html.haml +6 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/log/development.log +6643 -0
- data/spec/dummy/log/test.log +25990 -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/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/storage/.keep +0 -0
- data/spec/factories/how_tos.rb +9 -0
- data/spec/factories/ingredients.rb +11 -0
- data/spec/factories/recipes.rb +11 -0
- data/spec/factories/supplies.rb +9 -0
- data/spec/factories/tools.rb +9 -0
- data/spec/factories/users.rb +9 -0
- data/spec/factories/uses.rb +24 -0
- data/spec/helpers/cookbook/application_helper_spec.rb +47 -0
- data/spec/models/cookbook/use_spec.rb +82 -0
- data/spec/models/how_to_spec.rb +18 -0
- data/spec/models/ingredient_spec.rb +15 -0
- data/spec/models/recipe_spec.rb +18 -0
- data/spec/models/supply_spec.rb +15 -0
- data/spec/models/tool_spec.rb +15 -0
- data/spec/rails_helper.rb +92 -0
- data/spec/requests/how_tos_spec.rb +114 -0
- data/spec/requests/recipes_spec.rb +116 -0
- data/spec/spec_helper.rb +44 -0
- 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
|