如果验证失败,请在重新加载时保持更改

时间:2016-02-11 00:59:13

标签: ruby-on-rails validation ruby-on-rails-4 model rails-activerecord

我正在使用rails中的验证,例如:

validates_presence_of :some_field

我注意到如果验证失败,所有更改都会被数据库中的现有值覆盖。这是有道理的,因为页面基本上被重新加载(因为我从我的开发日志中收集),然而这增加了用户错误/挫折的风险,因为在一个字段中的单个错误将需要不幸的家伙重新进入他对所有领域所做的改变。

我的问题:如果验证失败,我怎样才能重新加载提交的数据?这样,用户可以纠正错误,而无需重新输入其他修订版本。

感谢您的任何建议。

修改 我的更新方法按要求如下:

def update
    @incorporation = Incorporation.find(params[:id])
    @company = @incorporation.company
    begin
        @company.name="#{params[:company][:names_attributes].values.first["name_string"]} #{params[:company][:names_attributes].values.first["suffix"]}"
    rescue NoMethodError
        @company.name="Company #{@company.id} (Untitled)"
    end
    if @company.update(company_params)
        redirect_to incorporations_index_path
    else
        redirect_to edit_incorporation_path(@incorporation)
    end
end

关于我的控制器的完整信息披露:上述update来自我的incorporations_controller,即使我正在更新我的Company模型。 Company has_one :incorporation。我这样做是因为,在我的应用程序的更大范围内,它使我的关联更清洁。

2 个答案:

答案 0 :(得分:2)

将您的控制器更新为此

def update
    @incorporation = Incorporation.find(params[:id])
    @company = @incorporation.company
    begin
        @company.name="#{params[:company][:names_attributes].values.first["name_string"]} #{params[:company][:names_attributes].values.first["suffix"]}"
    rescue NoMethodError
        @company.name="Company #{@company.id} (Untitled)"
    end
    respond_to do |format|
        if @company.update(company_params)
            format.html { redirect_to({:action => "index"})}
        else
            format.html{render :edit}
            format.json { render json: @incorporation.errors, status: :unprocessable_entity }
        end
    end
end

答案 1 :(得分:1)

要添加正确的答案,您可以清理一下代码:

def update
    @incorporation = Incorporation.find params[:id]

    respond_to do |format|
      if @incorporation.update company_params
        format.html { redirect_to({:action => "index"})}
      else
        format.html { render :edit }
        format.json { render json: @incorporation.errors, status: :unprocessable_entity }
      end
    end
end

如果你正在使用accepts_nested_attributes_for,你肯定应该破解前端的关联对象。

您应该查找fat model, skinny controller(让模型完成工作):

#app/models/company.rb
class Company < ActiveRecord::Base
  before_update :set_name
  attr_accessor :name_string, :name_suffix

  private

  def set_name
    if name_string && name_suffix
      self[:name] = "#{name_string} #{name_suffix}"
    else
      self[:name] = "Company #{id} (Untitled)"
    end
  end
end

这将允许您填充`公司的name。直接编辑嵌套/关联对象是antipattern;一个黑客,后来会回来困扰你。

答案的关键是:render :edit

渲染编辑视图意味着您可以维护当前的@company / @incorporation数据。

重定向将调用controller的新实例,覆盖@incorporation,因此您在前端看到的内容。