将 update_attributes 与 Rails 中的多个嵌套项一起使用时出错 5
Error when using update_attributes with multiple nested items in Rails 5
我有两个带有 has_many :through
连接模型的模型,如下所示:
class Brief < ApplicationRecord
has_many :brief_product_benefits
has_many :product_benefits, through: :brief_product_benefits
accepts_nested_attributes_for :brief_product_benefits, :allow_destroy => true
...
end
class ProductBenefit < ApplicationRecord
has_many :brief_product_benefits
has_many :briefs, through: :brief_product_benefits
end
class BriefProductBenefit < ApplicationRecord
belongs_to :brief
belongs_to :product_benefit
end
当我尝试通过 @brief.update_attributes
同时更新多个 BriefProductBenefit
对象时出现奇怪的错误。这是我得到的结果:
假设我像这样获取记录:
brief = Brief.find(1)
创建成功(插入两条新记录):
brief_params = {"brief_product_benefits_attributes"=>[{"id"=>"", "product_benefit_id"=>"1"}, {"id"=>"", "product_benefit_id"=>"2"}]}
brief.update_attributes(brief_params)
-> INSERT INTO "brief_product_benefits" ("brief_id", "product_benefit_id", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["brief_id", 2], ["product_benefit_id", 1], ["created_at", 2016-07-13 07:33:54 UTC], ["updated_at", 2016-07-13 07:33:54 UTC]]
-> INSERT INTO "brief_product_benefits" ("brief_id", "product_benefit_id", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["brief_id", 2], ["product_benefit_id", 2], ["created_at", 2016-07-13 07:33:54 UTC], ["updated_at", 2016-07-13 07:33:54 UTC]]
更新成功(更新product_benefit_id
):
brief_params = {"brief_product_benefits_attributes"=>[{"id"=>"3", "product_benefit_id"=>"2"}]}
brief.update_attributes(brief_params)
-> UPDATE "brief_product_benefits" SET "product_benefit_id" = , "updated_at" = WHERE "brief_product_benefits"."id" = [["product_benefit_id", 2], ["updated_at", 2016-07-13 07:35:10 UTC], ["id", 3]]
删除成功(删除id为3的BriefProductBenefit
):
brief_params = {"brief_product_benefits_attributes"=>[{"id"=>"3", "product_benefit_id"=>"2", "_destroy":true}]}
brief.update_attributes(brief_params)
-> DELETE FROM "brief_product_benefits" WHERE "brief_product_benefits"."id" = [["id", 3]]
发送嵌套对象数组时更新失败:
brief_params = {"brief_product_benefits_attributes"=>[{"id"=>"2", "product_benefit_id"=>"1"}, {"id"=>"3", "product_benefit_id"=>"1"}]}
brief.update_attributes(brief_params)
-> (0.1ms) BEGIN
-> (0.2ms) ROLLBACK
然后我得到以下堆栈跟踪:
ArgumentError: wrong number of arguments (given 1, expected 2)
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/reduce.rb:12:in `visit'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/postgres_ext-3.0.0/lib/postgres_ext/arel/4.1/visitors/postgresql.rb:22:in `block in visit_Array'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/postgres_ext-3.0.0/lib/postgres_ext/arel/4.1/visitors/postgresql.rb:22:in `map'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/postgres_ext-3.0.0/lib/postgres_ext/arel/4.1/visitors/postgresql.rb:22:in `visit_Array'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/reduce.rb:13:in `visit'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:641:in `visit_Arel_Nodes_In'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb:13:in `visit_Arel_Nodes_In'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/reduce.rb:13:in `visit'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:808:in `block in inject_join'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `each'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `each_with_index'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `each'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `inject'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `inject_join'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:657:in `visit_Arel_Nodes_And'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/reduce.rb:13:in `visit'
同样的问题,但操作简单,如 Post.where(id: [1,2,3])
Rails 5 也是,相同的 Arel 版本,相同的 reduce.rb 行
编辑:通过删除 gem 'postgres_ext' 修复,显然它还不支持 rails 5
我有两个带有 has_many :through
连接模型的模型,如下所示:
class Brief < ApplicationRecord
has_many :brief_product_benefits
has_many :product_benefits, through: :brief_product_benefits
accepts_nested_attributes_for :brief_product_benefits, :allow_destroy => true
...
end
class ProductBenefit < ApplicationRecord
has_many :brief_product_benefits
has_many :briefs, through: :brief_product_benefits
end
class BriefProductBenefit < ApplicationRecord
belongs_to :brief
belongs_to :product_benefit
end
当我尝试通过 @brief.update_attributes
同时更新多个 BriefProductBenefit
对象时出现奇怪的错误。这是我得到的结果:
假设我像这样获取记录:
brief = Brief.find(1)
创建成功(插入两条新记录):
brief_params = {"brief_product_benefits_attributes"=>[{"id"=>"", "product_benefit_id"=>"1"}, {"id"=>"", "product_benefit_id"=>"2"}]}
brief.update_attributes(brief_params)
-> INSERT INTO "brief_product_benefits" ("brief_id", "product_benefit_id", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["brief_id", 2], ["product_benefit_id", 1], ["created_at", 2016-07-13 07:33:54 UTC], ["updated_at", 2016-07-13 07:33:54 UTC]]
-> INSERT INTO "brief_product_benefits" ("brief_id", "product_benefit_id", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["brief_id", 2], ["product_benefit_id", 2], ["created_at", 2016-07-13 07:33:54 UTC], ["updated_at", 2016-07-13 07:33:54 UTC]]
更新成功(更新product_benefit_id
):
brief_params = {"brief_product_benefits_attributes"=>[{"id"=>"3", "product_benefit_id"=>"2"}]}
brief.update_attributes(brief_params)
-> UPDATE "brief_product_benefits" SET "product_benefit_id" = , "updated_at" = WHERE "brief_product_benefits"."id" = [["product_benefit_id", 2], ["updated_at", 2016-07-13 07:35:10 UTC], ["id", 3]]
删除成功(删除id为3的BriefProductBenefit
):
brief_params = {"brief_product_benefits_attributes"=>[{"id"=>"3", "product_benefit_id"=>"2", "_destroy":true}]}
brief.update_attributes(brief_params)
-> DELETE FROM "brief_product_benefits" WHERE "brief_product_benefits"."id" = [["id", 3]]
发送嵌套对象数组时更新失败:
brief_params = {"brief_product_benefits_attributes"=>[{"id"=>"2", "product_benefit_id"=>"1"}, {"id"=>"3", "product_benefit_id"=>"1"}]}
brief.update_attributes(brief_params)
-> (0.1ms) BEGIN
-> (0.2ms) ROLLBACK
然后我得到以下堆栈跟踪:
ArgumentError: wrong number of arguments (given 1, expected 2)
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/reduce.rb:12:in `visit'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/postgres_ext-3.0.0/lib/postgres_ext/arel/4.1/visitors/postgresql.rb:22:in `block in visit_Array'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/postgres_ext-3.0.0/lib/postgres_ext/arel/4.1/visitors/postgresql.rb:22:in `map'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/postgres_ext-3.0.0/lib/postgres_ext/arel/4.1/visitors/postgresql.rb:22:in `visit_Array'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/reduce.rb:13:in `visit'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:641:in `visit_Arel_Nodes_In'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb:13:in `visit_Arel_Nodes_In'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/reduce.rb:13:in `visit'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:808:in `block in inject_join'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `each'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `each_with_index'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `each'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `inject'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:806:in `inject_join'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/to_sql.rb:657:in `visit_Arel_Nodes_And'
from /Users/holiday/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/arel-7.0.0/lib/arel/visitors/reduce.rb:13:in `visit'
同样的问题,但操作简单,如 Post.where(id: [1,2,3]) Rails 5 也是,相同的 Arel 版本,相同的 reduce.rb 行
编辑:通过删除 gem 'postgres_ext' 修复,显然它还不支持 rails 5