如何保留 PORO 表单对象字段输入?
How to retain PORO Form object field inputs?
我创建了一个 R-o-R Form 对象,它接受属性,然后将这些属性保存到一些嵌套对象中,但是,如果验证失败,输入值就会消失。反正有没有办法留住他们?
class FormObject
include ActiveModel::Model
attr_accessor(:name, :date)
def initialize(params = {})
@params = params
end
def save
return if invalid?
no = NestedObject.new(nested_object_params)
no.save
end
def nested_object_params
@params.permit(:name, :date)
end
end
这是控制器
class Controller
def new
@form = FormObject.new
end
def create
@form = FormObject.new(form_object_params)
if @form.save
redirect_to ...
else
render :new
end
end
def form_object_params
params.require(:form_object).permit(:name, :date)
end
end
问题很可能是你在没有调用super的情况下覆盖了initialize方法。这搞乱了 ActiveModel::AttributeAssignment
完成的整个属性映射,表单真正依赖它来获取模型的属性。
class FormObject
include ActiveModel::Model
attr_accessor(:name, :date)
def initialize(params = {})
@params = params
super
end
def save
return if invalid?
no = NestedObject.new(nested_object_params)
no.save
end
def nested_object_params
@params.permit(:name, :date)
end
end
如果您使用 ActiveModel::Attributes
而不是 attr_accessor
中内置的 Ruby,您将获得类型转换,就像使用 ActiveRecord 支持的属性一样。
但这是一个直接的灾难,因为您现在拥有同一数据的三种不同表示形式:
- FormObject 上的实例变量
- 存储在@params中的散列
- 存储在 NestedObject 中的属性
相反,您可能应该完全重新考虑这一点并使用委托:
class FormObject
include ActiveModel::Model
attr_accessor :object
delegate :name, :name=, :date, :date=, :save, to: :object
def intialize(**attributes)
@object = NestedObject.new(attributes)
super
end
end
我创建了一个 R-o-R Form 对象,它接受属性,然后将这些属性保存到一些嵌套对象中,但是,如果验证失败,输入值就会消失。反正有没有办法留住他们?
class FormObject
include ActiveModel::Model
attr_accessor(:name, :date)
def initialize(params = {})
@params = params
end
def save
return if invalid?
no = NestedObject.new(nested_object_params)
no.save
end
def nested_object_params
@params.permit(:name, :date)
end
end
这是控制器
class Controller
def new
@form = FormObject.new
end
def create
@form = FormObject.new(form_object_params)
if @form.save
redirect_to ...
else
render :new
end
end
def form_object_params
params.require(:form_object).permit(:name, :date)
end
end
问题很可能是你在没有调用super的情况下覆盖了initialize方法。这搞乱了 ActiveModel::AttributeAssignment
完成的整个属性映射,表单真正依赖它来获取模型的属性。
class FormObject
include ActiveModel::Model
attr_accessor(:name, :date)
def initialize(params = {})
@params = params
super
end
def save
return if invalid?
no = NestedObject.new(nested_object_params)
no.save
end
def nested_object_params
@params.permit(:name, :date)
end
end
如果您使用 ActiveModel::Attributes
而不是 attr_accessor
中内置的 Ruby,您将获得类型转换,就像使用 ActiveRecord 支持的属性一样。
但这是一个直接的灾难,因为您现在拥有同一数据的三种不同表示形式:
- FormObject 上的实例变量
- 存储在@params中的散列
- 存储在 NestedObject 中的属性
相反,您可能应该完全重新考虑这一点并使用委托:
class FormObject
include ActiveModel::Model
attr_accessor :object
delegate :name, :name=, :date, :date=, :save, to: :object
def intialize(**attributes)
@object = NestedObject.new(attributes)
super
end
end