2016-06-29 38 views
0

基本上我想更新的Rails的模型中的每个表列5.更新在轨道的每一个数组对象价值

str = "abc---def" 

str.split('---').map do |a| 
Foo.where(product_id:1).update_all(bar: a) 
end 

旧的对象会是这样:

[ 
[0] { product_id: 1, 
     ..., 
     bar: "xxx", 
     ... 
    }, 
[1] { product_id: 1, 
     ..., 
     bar: "xxx", 
     ... 
    } 

] 

新应该是这样的:

[ 
[0] { product_id: 1, 
     ..., 
     bar: "abc", 
     ... 
    }, 
[1] { product_id: 1, 
     ..., 
     bar: "def", 
     ... 
    } 

] 

但是我得到的是每个bar: "def"。有没有一个干净的方法在轨道上实现我想要的? update_attributes提供了一个错误。

标题名称是否正确?

+0

首先你的问题不是那么明显。您如何期望在查询ID(主键)时返回多条记录? –

+1

让我告诉你我从你的问题中得到了什么。 所以你说你有一个值的数组(在字符串分割之后) 而且你有多个Model对象(在查询之后)并且你想要为模型设置相同顺序的每个值,对吗? –

+0

@QaisarNadeem谢谢你。发布更新。 – Sylar

回答

1

首先让我们从一些基础知识开始。

您想要更新多行并且想要为每一行设置不同的值。所以它不能像你正在做的那样在单个查询中完成。因此,您需要遍历Foo对象并分别设置每个对象。

因此,让我们假设

str = "abc---def---ghi---jkl" 
tokens = str.split('---') 
foos_to_update = Foo.where(product_id: 1) #Let's assume it will return 4 or lesser records. (otherwise you need to tell what do you wanna do if it returns more then `tokens`) 
foos_to_update.each_with_index {|foo,i| foo.update(bar: tokens[i])} 

最后一行是通过返回的对象进行循环并设置每个对象的bar值。

1

首先,使用Foo.where(id:1).update_all来更新单个记录可能有效,但是非惯用。最好使用Foo.find_by(id: 1).update。为了获取单个记录,我倾向于使用find_by而不是find,因为它返回nil而不是引发NotFound错误,但这是个人偏好。

其次,您使用update_all(bar: a)的方式会带给您意想不到的结果。在map块中,返回值成为结果数组的一部分。 update_all不会返回已更改的记录。它返回一个整数,显示已更改的记录数。同样,update不会返回记录。它根据验证是否通过返回true或false。

搭售这些概念放在一起,下面的代码可以写成:

str = "abc---def"  
str.split('---').map do |a| 
foo = Foo.find_by(id:1) 
foo&.update(bar: a) 
foo 
end 

# note that you could instead write `foo.update(bar: a)` if you 
# don't want to use the safe navigation operator 

或者另一种方式把它写它做同样的事情:

str = "abc---def" 
str.split('---').map do |a| 
Foo.find_by(id:1)&.tap { |foo| foo.update(bar: a) } 
end 

注意,在这些例子中,我使用在2.3以上的Ruby版本中的safe navigation operator。它有助于防止零点对象上的NoMethodError,但并不是真的有必要。

+0

'&.tap'是什么? Rails 5的方法? – Sylar

+0

[tap](http://ruby-doc.org/core-2.3.1/Object.html#method-i-tap)自1.9开始在Ruby核心中。这不是一个重要的使用方法。我认为它的好处主要是风格,增加可读性。 '&.'是我连接的安全导航操作符。 –

+0

我不得不接受Qaisar的回答,因为这对我来说更加清楚。然而。没有人回答工作。我已经尝试了很多次。最后的代码从未更新过表格列。首先在这里得到了一个语法错误:'foo&.update(file_file_name:a)' – Sylar

相关问题