lib/formtastic/actions/base.rb
# frozen_string_literal: true
module Formtastic
module Actions
module Base
include Formtastic::LocalizedString
attr_accessor :builder, :template, :object, :object_name, :method, :options
def initialize(builder, template, object, object_name, method, options)
@builder = builder
@template = template
@object = object
@object_name = object_name
@method = method
@options = options.dup
check_supported_methods!
end
def to_html
raise NotImplementedError
end
def wrapper(&block)
template.content_tag(:li,
template.capture(&block),
wrapper_html_options
)
end
def wrapper_html_options
wrapper_html_options_from_options.merge(default_wrapper_html_options)
end
def wrapper_html_options_from_options
options[:wrapper_html] || {}
end
def default_wrapper_html_options
{
:class => wrapper_class,
:id => wrapper_id
}
end
def wrapper_class
(default_wrapper_classes << wrapper_classes_from_options).join(" ")
end
def default_wrapper_classes
["action", "#{options[:as]}_action"]
end
def wrapper_classes_from_options
classes = wrapper_html_options_from_options[:class] || []
classes = classes.split(" ") if classes.is_a? String
classes
end
def wrapper_html_options_from_options
options[:wrapper_html] || {}
end
def wrapper_id
wrapper_id_from_options || default_wrapper_id
end
def wrapper_id_from_options
wrapper_html_options_from_options[:id]
end
def default_wrapper_id
"#{object_name}_#{method}_action"
end
def supported_methods
raise NotImplementedError
end
def text
text = options[:label]
text = (localized_string(i18n_key, text, :action, :model => sanitized_object_name) ||
Formtastic::I18n.t(i18n_key, :model => sanitized_object_name)) unless text.is_a?(::String)
text
end
def button_html
default_button_html.merge(button_html_from_options || {}).merge(extra_button_html_options)
end
def button_html_from_options
options[:button_html]
end
def extra_button_html_options
{}
end
def default_button_html
{ :accesskey => accesskey }
end
def accesskey
# TODO could be cleaner and separated, remember that nil is an allowed value for all of these
return options[:accesskey] if options.key?(:accesskey)
return options[:button_html][:accesskey] if options.key?(:button_html) && options[:button_html].key?(:accesskey)
# TODO might be different for cancel, etc?
return builder.default_commit_button_accesskey
end
protected
def check_supported_methods!
raise Formtastic::UnsupportedMethodForAction unless supported_methods.include?(method)
end
def i18n_key
return submit_i18n_key if method == :submit
method
end
def submit_i18n_key
if new_or_persisted_object?
key = @object.persisted? ? :update : :create
else
key = :submit
end
end
def new_or_persisted_object?
object && (object.respond_to?(:persisted?) || object.respond_to?(:new_record?))
end
def sanitized_object_name
if new_or_persisted_object?
# Deal with some complications with ActiveRecord::Base.human_name and two name models (eg UserPost)
# ActiveRecord::Base.human_name falls back to ActiveRecord::Base.name.humanize ("Userpost")
# if there's no i18n, which is pretty crappy. In this circumstance we want to detect this
# fall back (human_name == name.humanize) and do our own thing name.underscore.humanize ("User Post")
if object.class.model_name.respond_to?(:human)
sanitized_object_name = object.class.model_name.human
else
object_human_name = @object.class.human_name # default is UserPost => "Userpost", but i18n may do better ("User post")
crappy_human_name = @object.class.name.humanize # UserPost => "Userpost"
decent_human_name = @object.class.name.underscore.humanize # UserPost => "User post"
sanitized_object_name = (object_human_name == crappy_human_name) ? decent_human_name : object_human_name
end
else
sanitized_object_name = object_name.to_s.send(builder.label_str_method)
end
sanitized_object_name
end
end
end
end