-
Notifications
You must be signed in to change notification settings - Fork 184
How do I...?
property :foo, default: 'default'
This is a separate use case to "provide a default if empty" shown above. You want to do this if you want to set an initial value, but allow nil to be set as a value without it falling back to the default value when falsey.
# Remember to call `form.prepopulate!` to make this work.
property :foo, prepopulator: -> (*) { self.foo = "initial value" }
prepopulate!
is designed to called manually, but if you want to set a property value based on a property on the model, you can sneakily add it in the initializer.
def initialize *args
super(*args)
self.some_property = "#{model.some_property} #{model.some_other_property}"
end
class ItemForm < Reform::Form
...
end
class ListForm < Reform::Form
# entries is the name of the method on an array that will return itself
collection :entries, form: ItemForm
def each
entries.each { | entry | yield entry }
end
def map
entries.map { | entry | yield entry }
end
def count
entries.count
end
def empty?
entries.empty?
end
def any?
entries.any?
end
end
# in the controller
@items = ListForm.new(Item.all)
# in the UI - no change!
@items.each do | item |
...
end
class ListForm < Reform::Form
collection :entries, form: ItemForm
def initialize entries
super sort_entries(entries)
end
def sort_entries entries
entries{ | a, b| a.created_at <=> b.created_at }
end
end
For example, when you have a database validation like validates_uniqueness_of
, or you are using another gem that only plays with ActiveRecord models (eg. Devise).
This actually belongs in the Trailblazer::Operation docs... you could probably hack the same thing by overriding form.save
.
class User::Create < Trailblazer::Operation
def process(params)
validate(params[:user]) do | form |
unless form.save
model.errors.each do | key, message |
contract.errors.add(key, message)
end
invalid!
end
end
end
end
If you want to provide default values from an external source then you can use deserialize to populate the values without running the validations.
e.g. inside a controller
def new
form = MyForm.new(MyModel.new)
form.deserialize(params)
...
end