Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions demo/app/models/model_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class ModelUser
include ActiveModel::Model
attr_accessor :email, :password, :comments, :misc

validates :email, :password, presence: true
end
6 changes: 3 additions & 3 deletions lib/bootstrap_form/components/validation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def error?(name)
end

def association_error?(name)
object.class.reflections.any? do |association_name, a|
object.class.try(:reflections)&.any? do |association_name, a|
next unless a.is_a?(ActiveRecord::Reflection::BelongsToReflection)
next unless a.foreign_key == name.to_s

Expand All @@ -31,7 +31,7 @@ def required_attribute?(obj, attribute)
end

def required_association?(target, attribute)
target.reflections.find do |name, a|
target.try(:reflections)&.find do |name, a|
next unless a.is_a?(ActiveRecord::Reflection::BelongsToReflection)
next unless a.foreign_key == attribute.to_s

Expand Down Expand Up @@ -65,7 +65,7 @@ def generate_error(name)

def get_error_messages(name)
messages = object.errors[name]
object.class.reflections.each do |association_name, a|
object.class.try(:reflections)&.each do |association_name, a|
next unless a.is_a?(ActiveRecord::Reflection::BelongsToReflection)
next unless a.foreign_key == name.to_s

Expand Down
2 changes: 1 addition & 1 deletion lib/bootstrap_form/form_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class FormBuilder < ActionView::Helpers::FormBuilder
include BootstrapForm::Inputs::PhoneField
include BootstrapForm::Inputs::RadioButton
include BootstrapForm::Inputs::RangeField
include BootstrapForm::Inputs::RichTextArea if Rails::VERSION::MAJOR >= 6
include BootstrapForm::Inputs::RichTextArea
include BootstrapForm::Inputs::SearchField
include BootstrapForm::Inputs::Select
include BootstrapForm::Inputs::TelephoneField
Expand Down
2 changes: 1 addition & 1 deletion lib/bootstrap_form/inputs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module Inputs
autoload :PhoneField
autoload :RadioButton
autoload :RangeField
autoload :RichTextArea if Rails::VERSION::MAJOR >= 6
autoload :RichTextArea
autoload :SearchField
autoload :Select
autoload :TelephoneField
Expand Down
67 changes: 41 additions & 26 deletions test/special_form_class_models_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@ class SpecialFormClassModelsTest < ActionView::TestCase

test "Anonymous models are supported for form builder" do
user_klass = Class.new(User)

def user_klass.model_name
ActiveModel::Name.new(User)
end

@user = user_klass.new(email: "steve@example.com", password: "secret", comments: "my comment")
@builder = BootstrapForm::FormBuilder.new(:user, @user, self, {})
@horizontal_builder = BootstrapForm::FormBuilder.new(:user, @user, self, layout: :horizontal, label_col: "col-sm-2",
control_col: "col-sm-10")
I18n.backend.store_translations(:en, activerecord: {
help: {
user: { password: "A good password should be at least six characters long" }
}
})

@horizontal_builder =
BootstrapForm::FormBuilder.new(:user, @user, self, layout: :horizontal, label_col: "col-sm-2", control_col: "col-sm-10")
I18n.backend.store_translations(:en, activerecord: { help: { user: {
password: "A good password should be at least six characters long"
} } })
expected = <<~HTML
<div class="mb-3">
<label class="form-label" for="user_misc">Misc</label>
Expand All @@ -31,14 +29,11 @@ def user_klass.model_name
test "Nil models are supported for form builder" do
@user = nil
@builder = BootstrapForm::FormBuilder.new(:user, @user, self, {})
@horizontal_builder = BootstrapForm::FormBuilder.new(:user, @user, self, layout: :horizontal, label_col: "col-sm-2",
control_col: "col-sm-10")
I18n.backend.store_translations(:en, activerecord: {
help: {
user: { password: "A good password should be at least six characters long" }
}
})

@horizontal_builder =
BootstrapForm::FormBuilder.new(:user, @user, self, layout: :horizontal, label_col: "col-sm-2", control_col: "col-sm-10")
I18n.backend.store_translations(:en, activerecord: { help: { user: {
password: "A good password should be at least six characters long"
} } })
expected = <<~HTML
<div class="mb-3">
<label class="form-label" for="user_misc">Misc</label>
Expand All @@ -49,17 +44,13 @@ def user_klass.model_name
end

test "Objects without model names are supported for form builder" do
user_klass = FauxUser

@user = user_klass.new(email: "steve@example.com", password: "secret", comments: "my comment")
@user = FauxUser.new(email: "steve@example.com", password: "secret", comments: "my comment")
@builder = BootstrapForm::FormBuilder.new(:user, @user, self, {})
@horizontal_builder = BootstrapForm::FormBuilder.new(:user, @user, self, layout: :horizontal, label_col: "col-sm-2",
control_col: "col-sm-10")
I18n.backend.store_translations(:en, activerecord: {
help: {
faux_user: { password: "A good password should be at least six characters long" }
}
})
@horizontal_builder =
BootstrapForm::FormBuilder.new(:user, @user, self, layout: :horizontal, label_col: "col-sm-2", control_col: "col-sm-10")
I18n.backend.store_translations(:en, activerecord: { help: { faux_user: {
password: "A good password should be at least six characters long"
} } })

expected = <<~HTML
<div class="mb-3">
Expand All @@ -69,4 +60,28 @@ def user_klass.model_name
HTML
assert_equivalent_html expected, @builder.date_field(:misc)
end

test "ActiveModel objects are supported for form builder" do
@user = ModelUser.new(email: "steve@example.com", comments: "my comment")
assert_equal false, @user.valid?
@builder = BootstrapForm::FormBuilder.new(:user, @user, self, {})
@horizontal_builder = BootstrapForm::FormBuilder.new(:user, @user, self, layout: :horizontal, label_col: "col-sm-2",
control_col: "col-sm-10")
I18n.backend.store_translations(:en, activerecord: { help: { faux_user: {
password: "A good password should be at least six characters long"
} } })

expected = <<~HTML
<div class="mb-3">
<div class="field_with_errors">
<label class="form-label required" for="user_password">Password</label>
</div>
<div class="field_with_errors">
<input aria-required="true" class="form-control is-invalid" id="user_password" name="user[password]" required="required" type="text">
</div>
<div class="invalid-feedback">can#{Rails::VERSION::MAJOR < 7 ? "'" : '’'}t be blank</div>
</div>
HTML
assert_equivalent_html expected, @builder.text_field(:password)
end
end