我想用arel_table增加一个值我试试这个
update_manager = Arel::UpdateManager.new(ActiveRecord::Base)
i = Arel::Table.new(:items)
update_manager.table(i)
update_manager.where(i[:id].not_eq(id)).
set [ [ i[:order], i[:order] + 1 ] ]
但update_manager.to_sql返回:
"UPDATE \"items\" SET \"order\" = NULL"
我能怎么做 ?
同
set [ [ i[:order], i[:order] ] ]
我有
"UPDATE \"items\" SET \"order\" = \"items\".\"order\""
同
set [ [ i[:order], 1 ] ]
我有
"UPDATE \"items\" SET \"order\" = 1 "
你可以这样做
Item.where.not(id: id).where(a: a, b: b, c: c).update_all('order = order + 1')
至于Arel:
i[:items] + 1
# => #<Arel::Nodes::Grouping:0x000000074152d8 @expr=#<Arel::Nodes::Addition:0x00000007415300 @left=#<struct Arel::Attributes::Attribute relation=#<Arel::Table:0x000000074805b0 @name="items", @engine=ActiveRecord::Base, @columns=nil, @aliases=[], @table_alias=nil, @primary_key=nil>, name=:items>, @right=1, @operator=:+>>
它看起来像一个合理的Arel::Nodes::Grouping
,也
(i[:items] + 1).to_sql
# => "(\"items\".\"items\" + 1)"
所以这个事实
set [ [ i[:order], i[:order] + 1 ] ]
结果是
SET \"order\" = NULL
看起来更像是Arel中的一个错误。
仅供参考,如果您将(i[:items] + 1).to_sql
的结果传递给更新管理器
update_manager.set [ [ i[:order], (i[:order] + 1).to_sql ] ]
然后它将作为要分配的字符串值传递给SQL查询,而不是作为表达式(有意义):
UPDATE \"items\" SET \"order\" = '(\"items\".\"order\" + 1)'
因此,您需要编写一些额外的处理(例如,获取生成的sql字符串,切断这些引号,执行生成的sql)。但我个人会选择ActiveRecord
而不是Arel
。
您也可以查看Squeel gem。