在事务块失败后从参数哈希构建对象数组,Rails

Build array of objects from params hash after Transaction block fails, Rails

我有一个表单,用户可以在其中同时更新多个资源。事务块使表单具有原子性:如果任何正在更新的资源的验证失败,则 none 的资源将被更新,并且活动记录 rollsback 所有更改。

当交易失败时,我想再次呈现表单,显示用户输入的相同输入以及每个阻止交易通过的错误输入字段旁边的错误。

事务块有效。我遇到的问题是从参数日志构建对象数组。数组的每个索引都应包含一个散列,其中包含 key/value 对特定资源的所有属性。

更新:以下是响应代码

代码:

def update_multiple
  begin
    User.transaction do
      params[:users].each do |k, v|
      User.find(k).update!(v)
    end
    flash[:notice] = "Update Successful"
    redirect_to :users and return
  end
  rescue
    @users = []
    params[:users].each do |k,v|
      @users.push(User.new({:id => k}.merge(v))) 
    end
    flash[:error] = "Errors found"
    render :edit_multiple and return
  end
end

为了更好地衡量,这里是传入的参数在日志中的样子。此事务失败,因为名称属性的长度必须至少为 3 个字符。

Parameters: {"utf8"=>"✓", "authenticity_token"=>"xyz=", "users"=>{"15"=>
{"name"=>"Neil", "age"=>"11"}, "16"=>{"name"=>"z", "age"=>"33"}, "17"=>
{"name"=>"John", "age"=>"99"}}, "commit"=>"Submit Changes"}

提前致谢!在 ruby 中更好地编写此代码的任何方法也非常受欢迎。

好的,所以您尝试使用 for_each 和外部迭代器遍历参数中的对象列表,您真的不想这样做。我建议这样:

params[:users].each do |k,v|
  # k is the "key" of each user while v is the values associated with each key
  @users.push(User.new(:id => k, v)
  # I'm doing this in my head so you might need:
  # @users.push(User.new({:id => k}.merge(v)) 
  # if you start getting errors about looking for a proper hash or something
  # I can't remember how good Rails/Ruby is at recognizing nested hashes
end

这应该使用提供的 ID 和与每个值关联的值为传入的每个用户对象生成一个新用户。