Module: Airtable::ORM::Attributes

Extended by:
ActiveSupport::Concern
Included in:
Base
Defined in:
lib/airtable/orm/attributes.rb

Defined Under Namespace

Classes: AirtableArrayType

Constant Summary collapse

READ_ONLY_ATTRIBUTES =

Special read-only attributes that are not part of the Airtable fields

%i[id created_at].freeze

Instance Method Summary collapse

Instance Method Details

#[](key) ⇒ Object

Override [] to use symbol keys only



119
120
121
122
123
124
125
126
127
# File 'lib/airtable/orm/attributes.rb', line 119

def [](key)
  validate_symbol_key!(key)

  # Handle special read-only attributes
  return read_special_attribute(key) if special_attribute?(key)

  validate_regular_attribute!(key)
  public_send(key)
end

#[]=(key, value) ⇒ Object

Override []= to use symbol keys only



130
131
132
133
134
135
136
# File 'lib/airtable/orm/attributes.rb', line 130

def []=(key, value)
  validate_symbol_key!(key)
  validate_not_readonly!(key)
  validate_regular_attribute!(key)

  public_send("#{key}=", value)
end

#attribute_defined?(symbol) ⇒ Boolean

Check if attribute is defined (explicitly declared in the model class body)

Returns:

  • (Boolean)


218
219
220
# File 'lib/airtable/orm/attributes.rb', line 218

def attribute_defined?(symbol)
  self.class.attribute_types.key?(symbol.to_s)
end

#fields_for_createObject

Non-nil attributes with field IDs as keys (for CREATE).



160
161
162
# File 'lib/airtable/orm/attributes.rb', line 160

def fields_for_create
  map_attributes(key_type: :field_id, exclude_nil: true)
end

#fields_for_updateObject

Changed attributes with field IDs as keys (for UPDATE). Includes nil values.



165
166
167
# File 'lib/airtable/orm/attributes.rb', line 165

def fields_for_update
  map_attributes(key_type: :field_id, filter: ->(symbol) { changed.include?(symbol.to_s) })
end

#map_attributes(key_type:, exclude_nil: false, filter: nil) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/airtable/orm/attributes.rb', line 169

def map_attributes(key_type:, exclude_nil: false, filter: nil)
  return {} unless self.class.field_mapping

  self.class.field_mapping.each_with_object({}) do |(symbol, field_id), hash|
    next if filter && !filter.call(symbol)

    value = read_raw_attribute(symbol)
    next if exclude_nil && value.nil?

    key = key_type == :symbol ? symbol : field_id
    hash[key] = value
  end
end

#read_raw_attribute(key) ⇒ Object

Used by Associations to avoid infinite recursion when association name matches the attribute.



140
141
142
143
144
# File 'lib/airtable/orm/attributes.rb', line 140

def read_raw_attribute(key)
  return nil unless attribute_defined?(key)

  @attributes[key.to_s]&.value
end

#read_special_attribute(key) ⇒ Object

Read a special read-only attribute value



210
211
212
213
214
215
# File 'lib/airtable/orm/attributes.rb', line 210

def read_special_attribute(key)
  case key
  when :id then @id
  when :created_at then @created_at
  end
end

#special_attribute?(key) ⇒ Boolean

Check if this is a special read-only attribute

Returns:

  • (Boolean)


205
206
207
# File 'lib/airtable/orm/attributes.rb', line 205

def special_attribute?(key)
  READ_ONLY_ATTRIBUTES.include?(key)
end

#symbol_attributesObject

Get all attributes as a hash with symbol keys. Delegates to ActiveModel::Attributes#attributes which returns the same data with string keys.



155
156
157
# File 'lib/airtable/orm/attributes.rb', line 155

def symbol_attributes
  attributes.symbolize_keys
end

#validate_not_readonly!(key) ⇒ Object

Validate that key is not a read-only attribute



191
192
193
194
195
# File 'lib/airtable/orm/attributes.rb', line 191

def validate_not_readonly!(key)
  return unless READ_ONLY_ATTRIBUTES.include?(key)

  raise Airtable::ORM::InvalidAttributeError, "Cannot set read-only attribute: #{key.inspect}"
end

#validate_regular_attribute!(key) ⇒ Object

Validate that key is a known regular attribute (not special attributes like :id, :created_at)



198
199
200
201
202
# File 'lib/airtable/orm/attributes.rb', line 198

def validate_regular_attribute!(key)
  return if attribute_defined?(key)

  raise Airtable::ORM::UnknownFieldError, "Unknown field symbol: #{key.inspect}"
end

#validate_symbol_key!(key) ⇒ Object

Validate that key is a symbol



184
185
186
187
188
# File 'lib/airtable/orm/attributes.rb', line 184

def validate_symbol_key!(key)
  return if key.is_a?(Symbol)

  raise Airtable::ORM::InvalidAttributeError, "Only symbol keys are supported (e.g., record[:email])"
end

#write_raw_attribute(key, value) ⇒ Object



147
148
149
150
151
# File 'lib/airtable/orm/attributes.rb', line 147

def write_raw_attribute(key, value)
  return unless attribute_defined?(key)

  @attributes.write_from_user(key.to_s, value)
end