2015-04-25 116 views
0

我试图在一个易于阅读的格式化代码中列出一堆列。我知道我可能只是这样做:Rails更新基于数组的多列

@user = User.find(3) 
@user.column1 = nil 
@user.column2 = nil 
@user.column3 = nil 
etc... 

但是这似乎并不像一个很红宝石的方式做的事情,也不是特别干净阅读。

我试图弄清楚为什么我不能只是做一个“每个做”数组是这样的:

columns = [ "key", "provider", "uid", "access_code", 
       "customer_id", "cc_id", "cc_brand", "cc_last4", 
       "cc_expiration", "last_payment_id", "last_payment_date", 
       "last_payment_amount" ] 

columns.each do |record| 
    @user.record = nil 
end 

@user.save 

我收到以下错误:

undefined method `record=' for #<User:0x00000003a91d18> 

我知道类似的问题之前已经被问过,但他们通常与更新一堆不同的表格有关。我只对用户表感兴趣。

此外,还有很多答案链接到http://apidock.com/rails/ActiveRecord/Base/update_all/class。但是,这是一个旧的弃用方法,显然绕过回调。这似乎相当危险。

任何人都可以想到为什么一个简单的'每做'数组将无法正常工作?

回答

1

您可以使用动态函数的名称发送funtion:

@user.send("#{record}=", nil) 
+0

哇!快速有效的答案。这工作完美。谢谢!! – BoomShadow

+1

当然,为了解决这样的问题,提出了“发送”函数,你试图做的是为@user调用名为record的记录函数,而不是调用你想要的函数名称,这就是为什么它没有为这个对象引发任何称为记录的函数,如果你想获得属性的值,你也可以调用@ user.send(record) –

1

send也可以用来打电话与您的模型相关的(私有方法太)的方法。

然而,因为在你的情况,你只能编辑ActiveRecord的对象的字段(而不是调用任何方法),这里是一种替代方法:

columns = [ "key", "provider", "uid", "access_code", 
      "customer_id", "cc_id", "cc_brand", "cc_last4", 
      "cc_expiration", "last_payment_id", "last_payment_date", 
      "last_payment_amount" ] 

columns.each do |record| 
    @user[record] = nil 
end 

@user.save 
+0

这是一个很好的替代解决方案。阅读更清洁。我喜欢。 – BoomShadow

1

而不诉诸瑞士军刀另一种选择刀的send

columns = [ "key", "provider", "uid", "access_code", 
      "customer_id", "cc_id", "cc_brand", "cc_last4", 
      "cc_expiration", "last_payment_id", "last_payment_date", 
      "last_payment_amount" ] 

params = columns.map(&:to_sym).zip([nil]).to_h 

@user.update_attributes(params) 
+2

你可以在这里利用'zip'替代'inject'。 'columns.zip([nil])。to_h' – spike

+0

不错的@spike。编辑答案反映了这一点。 – fylooi