app/api/locomotive/api/forms/content_entry_form.rb
module Locomotive
module API
module Forms
class ContentEntryForm < BaseForm
NON_CUSTOM_FIELD_ATTRIBUTES = %w{_auth_reset_token _auth_reset_sent_at}
attr_accessor :content_type, :dynamic_attributes
attrs :_slug, :_position, :_visible, :seo_title, :meta_keywords, :meta_description
def initialize(content_type, attributes)
self.content_type = content_type
self.dynamic_attributes = {}
super(attributes)
end
def set_date_time(field, value)
dynamic_attributes[:"formatted_#{field.name}"] = value
end
alias :set_date :set_date_time
def set_belongs_to(field, value)
dynamic_attributes[field.name.to_sym] = fetch_entry_id(field.class_name, value)
end
def set_many_to_many(field, value)
if value.blank?
dynamic_attributes[:"#{field.name.singularize}_ids"] = [] # reset it
else
dynamic_attributes[:"#{field.name.singularize}_ids"] = fetch_entry_ids(field.class_name, value).sort do |a, b|
# keep the original order
(value.index(a.first.to_s) || value.index(a.last)) <=>
(value.index(b.first.to_s) || value.index(b.last))
end.map(&:first)
end
end
def method_missing(name, *args, &block)
if field = find_field(name)
if respond_to?(:"set_#{field.type}")
public_send(:"set_#{field.type}", field, args.first)
else
dynamic_attributes[getter_name(name).to_sym] = args.first
end
elsif NON_CUSTOM_FIELD_ATTRIBUTES.include?(getter_name(name))
dynamic_attributes[getter_name(name).to_sym] = args.first
else
super
end
end
def respond_to?(name, include_all = false)
find_field(name) || NON_CUSTOM_FIELD_ATTRIBUTES.include?(getter_name(name)) || super
end
def serializable_hash
super.merge(self.dynamic_attributes)
end
private
def getter_name(name)
name.to_s.gsub(/=\z/, '')
end
def find_field(name)
dynamic_setters[getter_name(name)]
end
def dynamic_setters
@dynamic_setters ||= self.content_type.entries_custom_fields.inject({}) do |hash, field|
case field.type.to_sym
when :password
hash[field.name] = hash["#{field.name}_confirmation"] = field
when :file
hash[field.name] = hash["remote_#{field.name}_url"] = hash["remove_#{field.name}"] = field
when :belongs_to
hash[field.name] = hash["position_in_#{field.name}"] = field
else
hash[field.name] = field
end
hash
end.with_indifferent_access
end
def fetch_entry_id(class_name, id_or_slug)
if entry = fetch_entry_ids(class_name, id_or_slug).first
entry.first
end
end
def fetch_entry_ids(class_name, ids_or_slugs)
return if ids_or_slugs.blank?
ids_or_slugs = [*ids_or_slugs]
klass = class_name.constantize
klass.by_ids_or_slugs(ids_or_slugs).pluck(:_id, :_slug)
end
end
end
end
end