• 分离出表单对象(Form Objects)


    https://github.com/angelfan/DayDayUp/blob/master/note/form_object.md#%E5%88%86%E7%A6%BB%E5%87%BA%E8%A1%A8%E5%8D%95%E5%AF%B9%E8%B1%A1form-objects

    分离出表单对象(Form Objects)

    step1

    class SignupForm
    
      include ActiveModel::Model
      include ActiveModel::Validations
    
      attr_accessor :user_name, department_id
    
      validates :user_name, presence: true
    
    
      def save
        if valid?
          # balabala
        else
          false
        end
      end
    
      def persisted?
        false
      end
    end

    缺点:

    • 属性没有类型
    • 设定default 值不是很方便

    step1

    借助 Virtus 增加default值

    class SignupForm
      include ActiveModel::Model
      include Virtus
    
      # Attributes (DSL provided by Virtus)
      attribute :user_name, String
      attribute :department_id, Integer default: 1
    
      # Validations
      validates :user_name, presence: true
    
      def save
        if valid?
          # balabala
        else
          false
        end
      end
    end

    resource

    other solution

    form sharetribe

    module FormUtils
      module_function
    
      # Define a form class that can be used with ActiveSupport form bindings
      #
      # Usage:
      #
      # -- in some_controller.rb --
      #
      # MyForm = FormUtils.define_form("MyForm", :name, :password)
      #   .with_validations { validates_presence_of :name }
      #
      # def new
      #   render locals: { form_obj: MyForm.new }
      # end
      #
      # def create
      #   myForm = MyForm.new(params[:my_form])
      #   if myForm.valid?
      #     ...
      #
      def define_form(form_name, *ks)
        Class.new(Object) { |klass|
          include ActiveModel::Validations
          include ActiveModel::Conversion
    
          @__keys = ks
          @__form_name = form_name
          @__validation_blocks = []
    
          def self.keys
            @__keys
          end
    
          def self.validation_blocks
            @__validation_blocks
          end
    
          attr_reader(*ks)
    
          def initialize(opts = {})
            keys_and_values = self.class.keys
              .map { |k| [k, opts[k]] }
              .reject { |(k, v)| v.nil? }
    
            keys_and_values.each { |(k, v)|
              instance_variable_set("@#{k.to_s}", v)
            }
    
            instance_variable_set("@__value_hash", Hash[keys_and_values])
          end
    
          def persisted?
            false
          end
    
          def to_hash
            @__value_hash
          end
    
          def self.model_name
            ActiveModel::Name.new(self, nil, @__form_name)
          end
    
          def self.with_validations(&block)
            @__validation_blocks << block
            class_exec(&block)
            self
          end
        }
      end
    
      def merge(form_name, *form_classes)
        keys = form_classes.map(&:keys).flatten
        validation_blocks = form_classes.map(&:validation_blocks).flatten
    
        form = FormUtils.define_form(form_name, *keys)
    
        validation_blocks.each do |block|
          form.with_validations(&block)
        end
    
        form
      end
    end
    
    SignupForm = FormUtils.define_form("SignupForm", :user_name, :department_id)
                  .with_validations { validates_presence_of :user_name }
  • 相关阅读:
    centos7 安装 supervisor
    远程桌面管理工具
    Delphi cxpagecontrol融合窗体
    Delphi调用网页美化SQL
    合并Dev BPL教程
    delphi 各新版本特性收集
    Delphi控件备份工具
    DBX Error: Driver could not be properly initialized..解决办法
    hugo 中文目录名 在 centos 的问题
    flutter Dialog里ListView的问题
  • 原文地址:https://www.cnblogs.com/angelfan/p/5268719.html
Copyright © 2020-2023  润新知