分離出表單對象(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-objectsgit

分離出表單對象(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值github

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 sharetribeweb

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 }
相關文章
相關標籤/搜索