- <% @members.each do |member| %>
-
- <%= member.name %>
-
- <% end %>
+
+
+ <% @members.each do |member| %>
+ -
+
+
+ <% end %>
+
+
+ <% @members.each do |member| %>
+
+ <%= render partial: 'member', locals: { member: } %>
+
+ <% end %>
+
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 053e0dd..d479d33 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -20,121 +20,17 @@
-
+ <%= render partial: 'header' %>
-
- <%= yield %>
-
+
diff --git a/config/application.rb b/config/application.rb
index 12c2cef..36d65aa 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -25,5 +25,7 @@ class Application < Rails::Application
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
+
+ config.i18n.default_locale = :it
end
end
diff --git a/config/initializers/simple_form_bootstrap.rb b/config/initializers/simple_form_bootstrap.rb
new file mode 100644
index 0000000..09ccabd
--- /dev/null
+++ b/config/initializers/simple_form_bootstrap.rb
@@ -0,0 +1,375 @@
+# frozen_string_literal: true
+
+# These defaults are defined and maintained by the community at
+# https://github.com/heartcombo/simple_form-bootstrap
+# Please submit feedback, changes and tests only there.
+
+# Uncomment this and change the path if necessary to include your own
+# components.
+# See https://github.com/heartcombo/simple_form#custom-components
+# to know more about custom components.
+# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
+
+# Use this setup block to configure all options available in SimpleForm.
+SimpleForm.setup do |config|
+ # Default class for buttons
+ config.button_class = 'btn'
+
+ # Define the default class of the input wrapper of the boolean input.
+ config.boolean_label_class = 'form-check-label'
+
+ # How the label text should be generated altogether with the required text.
+ config.label_text = ->(label, required, _explicit_label) { "#{label} #{required}" }
+
+ # Define the way to render check boxes / radio buttons with labels.
+ config.boolean_style = :inline
+
+ # You can wrap each item in a collection of radio/check boxes with a tag
+ config.item_wrapper_tag = :div
+
+ # Defines if the default input wrapper class should be included in radio
+ # collection wrappers.
+ config.include_default_input_wrapper_class = false
+
+ # CSS class to add for error notification helper.
+ config.error_notification_class = 'alert alert-danger'
+
+ # Method used to tidy up errors. Specify any Rails Array method.
+ # :first lists the first message for each field.
+ # :to_sentence to list all errors for each field.
+ config.error_method = :to_sentence
+
+ # add validation classes to `input_field`
+ config.input_field_error_class = 'is-invalid'
+ config.input_field_valid_class = 'is-valid'
+
+ # vertical forms
+ #
+ # vertical default_wrapper
+ config.wrappers :vertical_form, class: 'mb-3' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :maxlength
+ b.optional :minlength
+ b.optional :pattern
+ b.optional :min_max
+ b.optional :readonly
+ b.use :label, class: 'form-label'
+ b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # vertical input for boolean
+ config.wrappers :vertical_boolean, tag: 'fieldset', class: 'mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.wrapper :form_check_wrapper, class: 'form-check' do |bb|
+ bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
+ bb.use :label, class: 'form-check-label'
+ bb.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ bb.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # vertical input for radio buttons and check boxes
+ config.wrappers :vertical_collection,
+ item_wrapper_class: 'form-check',
+ item_label_class: 'form-check-label',
+ tag: 'fieldset',
+ class: 'mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
+ ba.use :label_text
+ end
+ b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # vertical input for inline radio buttons and check boxes
+ config.wrappers :vertical_collection_inline,
+ item_wrapper_class: 'form-check form-check-inline',
+ item_label_class: 'form-check-label',
+ tag: 'fieldset',
+ class: 'mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
+ ba.use :label_text
+ end
+ b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # vertical file input
+ config.wrappers :vertical_file, class: 'mb-3' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :maxlength
+ b.optional :minlength
+ b.optional :readonly
+ b.use :label, class: 'form-label'
+ b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # vertical select input
+ config.wrappers :vertical_select, class: 'mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.use :label, class: 'form-label'
+ b.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # vertical multi select
+ config.wrappers :vertical_multi_select, class: 'mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.use :label, class: 'form-label'
+ b.wrapper class: 'd-flex flex-row justify-content-between align-items-center' do |ba|
+ ba.use :input, class: 'form-select mx-1', error_class: 'is-invalid', valid_class: 'is-valid'
+ end
+ b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # vertical range input
+ config.wrappers :vertical_range, class: 'mb-3' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :readonly
+ b.optional :step
+ b.use :label, class: 'form-label'
+ b.use :input, class: 'form-range', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # horizontal forms
+ #
+ # horizontal default_wrapper
+ config.wrappers :horizontal_form, class: 'row mb-3' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :maxlength
+ b.optional :minlength
+ b.optional :pattern
+ b.optional :min_max
+ b.optional :readonly
+ b.use :label, class: 'col-sm-3 col-form-label'
+ b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
+ ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
+ ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ ba.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # horizontal input for boolean
+ config.wrappers :horizontal_boolean, class: 'row mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.wrapper :grid_wrapper, class: 'col-sm-9 offset-sm-3' do |wr|
+ wr.wrapper :form_check_wrapper, class: 'form-check' do |bb|
+ bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
+ bb.use :label, class: 'form-check-label'
+ bb.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ bb.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+ end
+
+ # horizontal input for radio buttons and check boxes
+ config.wrappers :horizontal_collection, item_wrapper_class: 'form-check', item_label_class: 'form-check-label',
+ class: 'row mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.use :label, class: 'col-sm-3 col-form-label pt-0'
+ b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
+ ba.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
+ ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
+ ba.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # horizontal input for inline radio buttons and check boxes
+ config.wrappers :horizontal_collection_inline, item_wrapper_class: 'form-check form-check-inline',
+ item_label_class: 'form-check-label', class: 'row mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.use :label, class: 'col-sm-3 col-form-label pt-0'
+ b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
+ ba.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
+ ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
+ ba.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # horizontal file input
+ config.wrappers :horizontal_file, class: 'row mb-3' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :maxlength
+ b.optional :minlength
+ b.optional :readonly
+ b.use :label, class: 'col-sm-3 col-form-label'
+ b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
+ ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
+ ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ ba.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # horizontal select input
+ config.wrappers :horizontal_select, class: 'row mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.use :label, class: 'col-sm-3 col-form-label'
+ b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
+ ba.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'
+ ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ ba.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # horizontal multi select
+ config.wrappers :horizontal_multi_select, class: 'row mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.use :label, class: 'col-sm-3 col-form-label'
+ b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
+ ba.wrapper class: 'd-flex flex-row justify-content-between align-items-center' do |bb|
+ bb.use :input, class: 'form-select mx-1', error_class: 'is-invalid', valid_class: 'is-valid'
+ end
+ ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }
+ ba.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # horizontal range input
+ config.wrappers :horizontal_range, class: 'row mb-3' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :readonly
+ b.optional :step
+ b.use :label, class: 'col-sm-3 col-form-label pt-0'
+ b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|
+ ba.use :input, class: 'form-range', error_class: 'is-invalid', valid_class: 'is-valid'
+ ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ ba.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # inline forms
+ #
+ # inline default_wrapper
+ config.wrappers :inline_form, class: 'col-12' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :maxlength
+ b.optional :minlength
+ b.optional :pattern
+ b.optional :min_max
+ b.optional :readonly
+ b.use :label, class: 'visually-hidden'
+
+ b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :error, wrap_with: { class: 'invalid-feedback' }
+ b.optional :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # inline input for boolean
+ config.wrappers :inline_boolean, class: 'col-12' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.wrapper :form_check_wrapper, class: 'form-check' do |bb|
+ bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
+ bb.use :label, class: 'form-check-label'
+ bb.use :error, wrap_with: { class: 'invalid-feedback' }
+ bb.optional :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # bootstrap custom forms
+ #
+ # custom input switch for boolean
+ config.wrappers :custom_boolean_switch, class: 'mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.wrapper :form_check_wrapper, tag: 'div', class: 'form-check form-switch' do |bb|
+ bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
+ bb.use :label, class: 'form-check-label'
+ bb.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
+ bb.use :hint, wrap_with: { class: 'form-text' }
+ end
+ end
+
+ # Input Group - custom component
+ # see example app and config at https://github.com/heartcombo/simple_form-bootstrap
+ config.wrappers :input_group, class: 'mb-3' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :maxlength
+ b.optional :minlength
+ b.optional :pattern
+ b.optional :min_max
+ b.optional :readonly
+ b.use :label, class: 'form-label'
+ b.wrapper :input_group_tag, class: 'input-group' do |ba|
+ ba.optional :prepend
+ ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
+ ba.optional :append
+ ba.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ end
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # Floating Labels form
+ #
+ # floating labels default_wrapper
+ config.wrappers :floating_labels_form, class: 'form-floating mb-3' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.optional :maxlength
+ b.optional :minlength
+ b.optional :pattern
+ b.optional :min_max
+ b.optional :readonly
+ b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :label
+ b.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # custom multi select
+ config.wrappers :floating_labels_select, class: 'form-floating mb-3' do |b|
+ b.use :html5
+ b.optional :readonly
+ b.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'
+ b.use :label
+ b.use :full_error, wrap_with: { class: 'invalid-feedback' }
+ b.use :hint, wrap_with: { class: 'form-text' }
+ end
+
+ # The default wrapper to be used by the FormBuilder.
+ config.default_wrapper = :vertical_form
+
+ # Custom wrappers for input types. This should be a hash containing an input
+ # type as key and the wrapper that will be used for all inputs with specified type.
+ config.wrapper_mappings = {
+ boolean: :vertical_boolean,
+ check_boxes: :vertical_collection,
+ date: :vertical_multi_select,
+ datetime: :vertical_multi_select,
+ file: :vertical_file,
+ radio_buttons: :vertical_collection,
+ range: :vertical_range,
+ time: :vertical_multi_select,
+ select: :vertical_select
+ }
+end
diff --git a/config/locales/simple_form.it.yml b/config/locales/simple_form.it.yml
new file mode 100644
index 0000000..84ca5a2
--- /dev/null
+++ b/config/locales/simple_form.it.yml
@@ -0,0 +1,39 @@
+it:
+ simple_form:
+ "yes": 'Si'
+ "no": 'No'
+ required:
+ text: 'obbligatorio'
+ mark: '*'
+ # You can uncomment the line below if you need to overwrite the whole required html.
+ # When using html, text and mark won't be used.
+ # html: '
*'
+ error_notification:
+ default_message: "Please review the problems below:"
+ labels:
+ member:
+ first_name: Nome
+ last_name: Cognome
+ born_at: Nato il
+ born_in: Nato a
+ tax_code: Codice fiscale
+ postal_code: CAP
+ municipality: Comune
+ province: Provincia
+ telephone: Telefono
+ email: Email
+ # user:
+ # new:
+ # email: 'E-mail to sign in.'
+ # edit:
+ # email: 'E-mail.'
+ # hints:
+ # defaults:
+ # username: 'User name to sign in.'
+ # password: 'No special characters, please.'
+ # include_blanks:
+ # defaults:
+ # age: 'Rather not say'
+ # prompts:
+ # defaults:
+ # age: 'Select your age'
diff --git a/config/routes.rb b/config/routes.rb
index 96d91b7..54bac07 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -3,5 +3,7 @@
Rails.application.routes.draw do
root to: 'home#index'
+ resources :members
+
get 'up' => 'rails/health#show', as: :rails_health_check
end
diff --git a/db/migrate/20240718060539_create_member.rb b/db/migrate/20240718060539_create_member.rb
index 6e96e49..44d4182 100644
--- a/db/migrate/20240718060539_create_member.rb
+++ b/db/migrate/20240718060539_create_member.rb
@@ -3,15 +3,16 @@
class CreateMember < ActiveRecord::Migration[7.2]
def change
create_table :members do |t|
- t.string :name, null: false
- t.string :surname, null: false
+ t.string :first_name, null: false
+ t.string :last_name, null: false
t.date :born_at, null: false
t.string :born_in, null: false
t.string :tax_code
t.string :citizenship, null: false
t.string :address, null: false
t.string :postal_code, null: false
- t.string :province
+ t.string :municipality, null: false
+ t.string :province, null: false
t.string :telephone
t.string :email
diff --git a/db/schema.rb b/db/schema.rb
index eefba89..e342cf8 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -19,15 +19,16 @@
end
create_table "members", force: :cascade do |t|
- t.string "name", null: false
- t.string "surname", null: false
+ t.string "first_name", null: false
+ t.string "last_name", null: false
t.date "born_at", null: false
t.string "born_in", null: false
t.string "tax_code"
t.string "citizenship", null: false
t.string "address", null: false
t.string "postal_code", null: false
- t.string "province"
+ t.string "municipality", null: false
+ t.string "province", null: false
t.string "telephone"
t.string "email"
t.text "notes"
diff --git a/db/seeds.rb b/db/seeds.rb
index a72d4ef..9912a6a 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -15,13 +15,17 @@
Faker::Config.locale = 'it'
10.times do
- Member.create(
- name: Faker::Name.first_name,
- surname: Faker::Name.last_name,
+ Member.create!(
+ first_name: Faker::Name.first_name,
+ last_name: Faker::Name.last_name,
born_at: Faker::Date.between(from: '2015-12-31', to: '2000-01-01'),
born_in: Faker::Address.city,
citizenship: Faker::Address.country,
address: Faker::Address.full_address,
- postal_code: Faker::Address.postcode
+ postal_code: Faker::Address.postcode,
+ municipality: Faker::Address.community,
+ province: Faker::Address.community.first(2),
+ telephone: Faker::PhoneNumber.cell_phone,
+ email: Faker::Internet.email
)
end
diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb
new file mode 100644
index 0000000..106b71e
--- /dev/null
+++ b/lib/templates/erb/scaffold/_form.html.erb
@@ -0,0 +1,15 @@
+<%# frozen_string_literal: true %>
+<%%= simple_form_for(@<%= singular_table_name %>) do |f| %>
+ <%%= f.error_notification %>
+ <%%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+
+
+ <%- attributes.each do |attribute| -%>
+ <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
+ <%- end -%>
+
+
+
+ <%%= f.button :submit %>
+
+<%% end %>
diff --git a/test/models/member_test.rb b/test/models/member_test.rb
index 0089690..159c596 100644
--- a/test/models/member_test.rb
+++ b/test/models/member_test.rb
@@ -6,8 +6,8 @@ class MemberTest < ActiveSupport::TestCase
test 'valudates presence' do
member = Member.create
- assert(member.errors.key?('name'))
- assert(member.errors.key?('surname'))
+ assert(member.errors.key?('first_name'))
+ assert(member.errors.key?('last_name'))
assert(member.errors.key?('born_at'))
assert(member.errors.key?('born_in'))
assert(member.errors.key?('citizenship'))