Class: CafeCar::FieldInfo
- Inherits:
-
Object
- Object
- CafeCar::FieldInfo
- Defined in:
- lib/cafe_car/field_info.rb
Constant Summary collapse
- @@reflections_by_attribute =
{}
Instance Attribute Summary collapse
-
#method ⇒ Object
(also: #name)
readonly
Returns the value of attribute method.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
Instance Method Summary collapse
- #abrogated_keys ⇒ Object
- #associated? ⇒ Boolean
- #association? ⇒ Boolean
- #attachment? ⇒ Boolean
- #attachment_type ⇒ Object
- #attribute_type ⇒ Object
- #autocomplete ⇒ Object
- #collection(scope = reflection.klass.all) ⇒ Object
- #constant? ⇒ Boolean
- #default_type ⇒ Object
- #digest? ⇒ Boolean
- #digest_type ⇒ Object
- #displayable ⇒ Object
- #enum? ⇒ Boolean
- #enum_type ⇒ Object
- #hint ⇒ Object
- #human ⇒ Object
- #i18n(key, **opts) ⇒ Object
- #i18n_key ⇒ Object
- #id? ⇒ Boolean
- #info(method) ⇒ Object
-
#initialize(model:, method:) ⇒ FieldInfo
constructor
A new instance of FieldInfo.
- #input ⇒ Object
- #input_key ⇒ Object
- #label ⇒ Object
- #multiple? ⇒ Boolean
- #nested_attributes_type ⇒ Object
- #password? ⇒ Boolean
- #placeholder ⇒ Object
- #polymorphic? ⇒ Boolean
- #polymorphic_methods ⇒ Object
- #prompt ⇒ Object
- #reflection ⇒ Object
- #reflection_type ⇒ Object
- #reflections_by_attribute ⇒ Object
- #required? ⇒ Boolean
- #rich_text? ⇒ Boolean
- #timestamp? ⇒ Boolean
- #type ⇒ Object
- #validator?(kind, **options) ⇒ Boolean
- #values ⇒ Object
- #width ⇒ Object
Constructor Details
#initialize(model:, method:) ⇒ FieldInfo
Returns a new instance of FieldInfo.
8 9 10 11 12 |
# File 'lib/cafe_car/field_info.rb', line 8 def initialize(model:, method:) # raise "Cannot get FieldInfo for nil method" if method.nil? @method = method&.to_sym @model = model end |
Instance Attribute Details
#method ⇒ Object (readonly) Also known as: name
Returns the value of attribute method.
3 4 5 |
# File 'lib/cafe_car/field_info.rb', line 3 def method @method end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
3 4 5 |
# File 'lib/cafe_car/field_info.rb', line 3 def model @model end |
Instance Method Details
#abrogated_keys ⇒ Object
44 45 46 |
# File 'lib/cafe_car/field_info.rb', line 44 def abrogated_keys [ *reflection&.foreign_type&.to_sym ] end |
#associated? ⇒ Boolean
25 |
# File 'lib/cafe_car/field_info.rb', line 25 def associated? = reflection.present? |
#association? ⇒ Boolean
20 21 22 23 |
# File 'lib/cafe_car/field_info.rb', line 20 def association? return if @method.nil? model.reflect_on_association(@method).present? end |
#attachment? ⇒ Boolean
32 |
# File 'lib/cafe_car/field_info.rb', line 32 def = model.(method) |
#attachment_type ⇒ Object
64 65 66 |
# File 'lib/cafe_car/field_info.rb', line 64 def :attachment if end |
#attribute_type ⇒ Object
58 |
# File 'lib/cafe_car/field_info.rb', line 58 def attribute_type = model.type_for_attribute(@method)&.type |
#autocomplete ⇒ Object
76 |
# File 'lib/cafe_car/field_info.rb', line 76 def autocomplete = i18n(:autocomplete) |
#collection(scope = reflection.klass.all) ⇒ Object
34 |
# File 'lib/cafe_car/field_info.rb', line 34 def collection(scope = reflection.klass.all) = scope.limit(CafeCar.) |
#constant? ⇒ Boolean
17 |
# File 'lib/cafe_car/field_info.rb', line 17 def constant? = method.in? %i[id created_at updated_at] |
#default_type ⇒ Object
50 51 52 53 54 |
# File 'lib/cafe_car/field_info.rb', line 50 def default_type case method when :controls, :select then method end end |
#digest? ⇒ Boolean
27 |
# File 'lib/cafe_car/field_info.rb', line 27 def digest? = method =~ /_digest$/ |
#digest_type ⇒ Object
59 60 61 62 |
# File 'lib/cafe_car/field_info.rb', line 59 def digest_type key = @method.to_s.chomp("_confirmation") model.type_for_attribute("#{key}_digest")&.type && :password end |
#displayable ⇒ Object
48 |
# File 'lib/cafe_car/field_info.rb', line 48 def displayable = reflection&.name&.then { info(_1) } || self |
#enum? ⇒ Boolean
28 |
# File 'lib/cafe_car/field_info.rb', line 28 def enum? = model.try(:defined_enums)&.key?(@method.to_s) |
#enum_type ⇒ Object
57 |
# File 'lib/cafe_car/field_info.rb', line 57 def enum_type = (:enum if enum?) |
#hint ⇒ Object
77 |
# File 'lib/cafe_car/field_info.rb', line 77 def hint = i18n(:hint) |
#human ⇒ Object
80 |
# File 'lib/cafe_car/field_info.rb', line 80 def human(...) = @method&.then { model.human_attribute_name(_1, ...) } |
#i18n(key, **opts) ⇒ Object
88 89 90 91 92 |
# File 'lib/cafe_car/field_info.rb', line 88 def i18n(key, **opts) return if @method.nil? I18n.t(@method, scope: [ :helpers, key, i18n_key ], raise: true, **opts) rescue I18n::MissingTranslationData end |
#i18n_key ⇒ Object
87 |
# File 'lib/cafe_car/field_info.rb', line 87 def i18n_key = model_name.i18n_key |
#id? ⇒ Boolean
16 |
# File 'lib/cafe_car/field_info.rb', line 16 def id? = method =~ /_ids?$/ |
#info(method) ⇒ Object
14 |
# File 'lib/cafe_car/field_info.rb', line 14 def info(method) = model.info.field(method) |
#input ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/cafe_car/field_info.rb', line 112 def input case type when :string then :text_field when :decimal then :text_field when :text, :json then :text_area when :integer then :number_field when :boolean then :check_box when :date then :date_field when :datetime then :datetime_field when :password then :password_field when :nested then :fields_for when :enum then :enum when :attachment then :file_field when :belongs_to, :has_many then :association when :has_one rich_text? ? :rich_text_area : nil else raise "Missing input type for #{model_name}##{@method} of type :#{type}" end end |
#input_key ⇒ Object
132 133 134 135 136 137 |
# File 'lib/cafe_car/field_info.rb', line 132 def input_key case type when :belongs_to then reflection.foreign_key else method end end |
#label ⇒ Object
78 |
# File 'lib/cafe_car/field_info.rb', line 78 def label = i18n(:label, default: human) |
#multiple? ⇒ Boolean
33 |
# File 'lib/cafe_car/field_info.rb', line 33 def multiple? = &.macro == :has_many_attached |
#nested_attributes_type ⇒ Object
68 69 70 71 |
# File 'lib/cafe_car/field_info.rb', line 68 def nested_attributes_type key = @method.to_s.chomp("_attributes").to_sym :nested if model..key?(key) end |
#password? ⇒ Boolean
30 |
# File 'lib/cafe_car/field_info.rb', line 30 def password? = type == :password |
#placeholder ⇒ Object
75 |
# File 'lib/cafe_car/field_info.rb', line 75 def placeholder = i18n(:placeholder) |
#polymorphic? ⇒ Boolean
26 |
# File 'lib/cafe_car/field_info.rb', line 26 def polymorphic? = reflection&.polymorphic? |
#polymorphic_methods ⇒ Object
73 |
# File 'lib/cafe_car/field_info.rb', line 73 def polymorphic_methods = [ reflection.foreign_type, reflection.foreign_key ] |
#prompt ⇒ Object
79 |
# File 'lib/cafe_car/field_info.rb', line 79 def prompt = i18n(:prompt, default: "Select #{human.downcase}...") |
#reflection ⇒ Object
35 36 37 38 39 40 41 42 |
# File 'lib/cafe_car/field_info.rb', line 35 def reflection return if @method.nil? # A nested-attributes permit names the key `<assoc>_attributes` (what Rails' # strong-params and `fields_for` use) — resolve it back to the association, # the same way `nested_attributes_type` chomps the suffix. key = @method.to_s.chomp("_attributes") model.try(:reflect_on_association, key) || reflections_by_attribute[key] end |
#reflection_type ⇒ Object
56 |
# File 'lib/cafe_car/field_info.rb', line 56 def reflection_type = reflection&.macro |
#reflections_by_attribute ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/cafe_car/field_info.rb', line 140 def reflections_by_attribute return {} unless model.respond_to? :reflections @@reflections_by_attribute[model] ||= model.reflections.values.index_by do |r| case [ r.macro, r.name ] in [ :belongs_to, * ] then r.foreign_key in [ :has_many, * ] then "#{r.name.to_s.singularize}_ids" in [ :has_one, /^rich_text_(\w+)$/ ] then $1 in [ :has_one, * ] then r.name else raise NoMethodError.new("Not yet implemented :#{r.macro}") end end.with_indifferent_access end |
#required? ⇒ Boolean
81 |
# File 'lib/cafe_car/field_info.rb', line 81 def required? = validator?(:presence) |
#rich_text? ⇒ Boolean
31 |
# File 'lib/cafe_car/field_info.rb', line 31 def rich_text? = reflection&.name =~ /^rich_text_(\w+)$/ |
#timestamp? ⇒ Boolean
18 |
# File 'lib/cafe_car/field_info.rb', line 18 def = type.in? %i[date datetime time] |
#type ⇒ Object
94 95 96 97 98 99 |
# File 'lib/cafe_car/field_info.rb', line 94 def type return if @method.nil? @type ||= nested_attributes_type || reflection_type || enum_type || attribute_type || digest_type || || default_type || raise(NoMethodError.new "Can't find attribute :#{@method} on #{model_name}", @method) end |
#validator?(kind, **options) ⇒ Boolean
83 84 85 |
# File 'lib/cafe_car/field_info.rb', line 83 def validator?(kind, **) model.validators_on(@method).any? { _1.kind == kind and _1. >= } end |
#values ⇒ Object
29 |
# File 'lib/cafe_car/field_info.rb', line 29 def values = model.defined_enums[@method.to_s].keys |
#width ⇒ Object
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/cafe_car/field_info.rb', line 101 def width case type when :text, :string, :json # "minmax(10em, fit-content)" # "minmax(10em, 1fr)" "minmax(10em, auto)" # "minmax(min-content, auto)" else "min-content" end end |