class PassionView::Form::Base

Constants

Delegation

Public Class Methods

delegate(*methods) click to toggle source
# File lib/passion_view/form/base.rb, line 63
def delegate(*methods)
  options = methods.pop
  unless options.is_a?(Hash) && (to = options[:to])
    raise ArgumentError, 'Delegation needs a target'
  end

  prefix, = options.values_at(:prefix, :allow_nil)
  cast = options[:cast]
  writer = options[:accessor] || !cast.nil?

  method_prefix = "#{prefix == true ? to : prefix}_" if prefix

  delegations << Delegation.new(
    to,
    method_prefix,
    methods,
    cast,
    writer,
  )

  caster = caster_for(cast)

  raise ArgumentError, ':errors not allowed' if methods.include?(:errors)

  methods.each do |method|
    permit("#{method_prefix}#{method}")
  end if writer
  methods += methods.map { |method| "#{method}=" } if writer

  methods.each do |method|
    if method =~ /[^\]]=$/
      define_method("#{method_prefix}#{method}") do |arg|
        instance_variable_set("@#{method_prefix}#{method.gsub(/=$/, '')}_before_type_cast", arg)
        arg = caster.call(arg) unless caster.nil?
        instance_eval("self.#{to}").send(method, arg)
      end

      define_method("#{method_prefix}#{method.to_s.gsub(/=$/, '')}_before_type_cast") do
        instance_variable_get("@#{method_prefix}#{method.gsub(/=$/, '')}_before_type_cast") || send("#{method_prefix}#{method.gsub(/=$/, '')}")
      end
    else
      define_method("#{method_prefix}#{method}") do |*args, &block|
        instance_eval("self.#{to}").try(:send, method, *args, &block)
      end
    end
  end
end
delegations(inherited: false) click to toggle source
# File lib/passion_view/form/base.rb, line 111
def delegations(inherited: false)
  @delegations ||= []
  return @delegations unless inherited && superclass.respond_to?(:delegations)
  @delegations + superclass.delegations(inherited: true)
end
i18n_scope() click to toggle source
# File lib/passion_view/form/base.rb, line 5
def self.i18n_scope
  :forms
end
permit(*methods) click to toggle source
# File lib/passion_view/form/base.rb, line 59
def permit(*methods)
  permitted_params.concat(methods)
end
permitted_params() click to toggle source
# File lib/passion_view/form/base.rb, line 117
def permitted_params
  @permitted_params ||= []
end

Private Class Methods

caster_for(cast_type) click to toggle source
# File lib/passion_view/form/base.rb, line 123
def caster_for(cast_type)
  case cast_type
  when :date     then ->(v) { Date.parse(v) if v =~ /\A\d\d\d\d-\d\d-\d\d\z/ }
  when :datetime then ->(v) { Time.zone.parse(v) if v =~ /\A\d\d\d\d-\d\d-\d\d \d\d:\d\d\z/ }
  when :boolean  then ->(v) { (%w(1 true yes) + %w(0 false no)).include?(v) ? %w(1 true yes).include?(v) : nil }
  when :integer  then ->(v) { v.to_i if v =~ /\A[-+]?\d+\z/ }
  when :float    then ->(v) { v.to_f if v =~ /\A[-+]?\d+(?:\.\d+|)\z/ }
  when :decimal  then ->(v) { BigDecimal.new(v) if v =~ /\A[-+]?\d+(?:\.\d+|)\z/ }
  when :blank    then nil
  when Proc      then cast_type
  else                ->(v) { v unless v.blank? }
  end
end

Public Instance Methods

assign_attributes(new_attributes) click to toggle source
# File lib/passion_view/form/base.rb, line 41
def assign_attributes(new_attributes)
  new_attributes.permit(*permitted_params)

  new_attributes.each do |k, v|
    send("#{k}=", v) if respond_to?("#{k}=")
  end
end
permitted_params() click to toggle source
# File lib/passion_view/form/base.rb, line 54
def permitted_params
  self.class.permitted_params
end
persisted?() click to toggle source
# File lib/passion_view/form/base.rb, line 17
def persisted?
  false
end
update_attributes(new_attributes) click to toggle source
# File lib/passion_view/form/base.rb, line 49
def update_attributes(new_attributes)
  assign_attributes(new_attributes)
  valid? && save
end
valid?() click to toggle source
Calls superclass method
# File lib/passion_view/form/base.rb, line 21
def valid?
  [super].concat(self.class.delegations(inherited: true).map do |delegation|
    item = instance_eval("self.#{delegation.to} rescue nil")
    next if item.nil?
    result = item.respond_to?(:valid?) ? item.valid? : true

    # TODO: tester les validations des models
    #       du type "validates :qqch(sans _id), presence: true"
    if item.respond_to?(:errors)
      item.errors.messages.each do |method, messages|
        messages.each do |message|
          errors.add(:"#{delegation.prefix}#{method}", message) unless errors[:"#{delegation.prefix}#{method}"].include?(message)
        end if item.methods.include?(method)
      end
    end

    result
  end).compact.reduce(:&)
end