我想更改编辑密码进程。在编辑密码页面上,我有一个字段:foo,我想检查用户是否正确输入了它。
我创建了PasswordsController并覆盖了更新方法,我在其中添加了用于测试的代码:foo与数据库中的相同:
def update
self.resource = resource_class.reset_password_by_token(resource_params)
# this is code that I added
unless self.resource.foo == params[resource_name][:foo]
self.resource.errors.add(:foo, "Foo not correct")
end
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message(:notice, flash_message) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_resetting_password_path_for(resource)
else
binding.pry
respond_with resource
end
end
假设我输入" test" in:foo field,但在数据库中,它的值是" fake"。它将在视图上打印错误(" Foo不正确")但它将填充:foo字段,其中包含来自数据库的值(" fake")而不是我输入的值(" test& #34;。)
我应该重新定义reset_password_by_token或使用我的自定义方法,但想知道是否有更优雅的方法来解决这个问题?
答案 0 :(得分:1)
尝试使用before_action(可能是before_filter,具体取决于您的Rails版本):
class PasswordsController < ...
before_action :check_foo, :only => :update
...
private
def check_foo
# get resource
# check foo
# redirect if foo is not valid
end
end
您也可以将其更改为仅扩展现有RegistrationsController
。只需重新使用update
的现有Devise实现,而无需重新实现它,只需在前面添加过滤器。
要阻止更新对象上的:foo
,请先过滤params
哈希,删除:foo
字段,然后再将其传递给reset_password_by_token
。
def remove_foo(hash)
hash.delete_if { |k, v| k == :foo }
end
...
self.resource = resource_class.reset_password_by_token(remove_foo(resource_params))
或者,如果您使用Rails 4, or Strong Parameters,请不要允许。
答案 1 :(得分:0)
为表单上的字段使用不同的名称(假设为'bar')然后您将测试更改为:
...
unless self.resource.foo == params[resource_name][:bar]
self.resource.errors.add(:foo, "Foo not correct")
end
...
注意:在视图中,您将无法使用表单构建器的东西,因为如果'bar'不是模型对象的属性,它会阻塞,但您可以使用html直接向表单添加任何标记或像FormTagHelper::text_field_tag
这样的rails辅助方法。