ruby-on-rails - Rails ActiveRecord 嵌套 .create!使用 PSQL POINT 类型
问题描述
我正在尝试使用 Rails 和 ActiveRecord 创建一个深度嵌套的对象。
Order.create!(params)
该模型包含一个Address
具有coordinates
PSQL 类型 POINT 字段的子模型。
因此,当我尝试创建它时,出现以下错误。我猜它试图通过使用提供的字段首先加载类型,但由于没有比较Address
而挂断在(POINT) 类型上(根据https://www.postgresql.org/docs/13 /functions-geometry.html)。coordinates
=
~=
所以我的问题......有没有办法向 ActiveRecord 提供提示以帮助它正确执行此查询,或者我应该如何解决这个问题?
Address Load (0.7ms) SELECT "addresses".* FROM "addresses" WHERE "addresses"."firstname" = '-' AND "addresses"."lastname" = '-' AND "addresses"."phone" = '-' AND "addresses"."coordinates" = '-74.0064172,40.7049028' AND "addresses"."address1" = '110 Wall St' AND "addresses"."address2" = '' AND "addresses"."city" = 'New York' AND "addresses"."zipcode" = '10005' AND "addresses"."state_id" = 1 AND "addresses"."country_id" = 1 LIMIT 1
↳ app/services/cart/create_cart_service_decorator.rb:21:in `call'
PG::UndefinedFunction: ERROR: operator does not exist: point = unknown
LINE 1: ..."phone" = '-' AND "addresses"."coordinates" = '-74.006...
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
这是一个独立的文件来重现这一点。
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# Activate the gem you are reporting the issue against.
gem "activerecord", "6.1.3.2"
gem "pg"
end
require "active_record"
require "minitest/autorun"
require "logger"
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "postgresql", database: "test-db")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :addresses, force: true do |t|
t.point :coordinates
end
end
class Address < ActiveRecord::Base
end
class BugTest < Minitest::Test
def test_nested_saving
address = Address.find_or_create_by!({ coordinates: ActiveRecord::Point.new(0, 0) })
assert address
end
end
解决方案
您需要将参数显式类型转换为 ActiveRecord::Point 实例,从某些版本开始就支持该实例:
x, y = params[:coordinates].split(',').map(&:to_f)
params[:coordinates] = ActiveRecord::Point.new(x, y)
推荐阅读
- mysql - 使用三表mysql连接查询
- java - 从远程服务获取数据哪种方式更好
- android - Ionic Android 设备测试失败
- php - 从一个文件夹复制,解密然后使用 PHP 解压缩
- android - 如何从 XML 文件运行动画?
- html - Flexbox 显示动态项目数,每行 5 个项目,使用 flex 基础来消耗额外空间
- sql - PostgreSQL 为 varchar-timestamp 转换返回错误的值
- ios - 自定义 UITextField 中的边框宽度和占位符
- javascript - 传播运算符不作为 {...this.state.attributes} 工作
- java - Java Swing Jinternalframe 浏览器