这很难找到相关信息。这一切的关键是我有一个Rails 3.2应用程序,它使用POINT
类型的列访问MySQL数据库表。没有非本机代码,rails不知道如何解释这个,这很好,因为我只在内部数据库查询中使用它。
然而,问题是它被转换为整数,并且如果为空则强制为null。 MySQL不允许对该字段使用null,因为它上面有索引,并且整数无效,所以这实际上意味着我无法通过rails创建新记录。
我一直在寻找一种方法来在插入数据库之前更改值,但是我的轨道上的光线不足以点亮它。到目前为止,我已尝试过以下内容:
...
after_validation :set_geopoint_blank
def set_geopoint_blank
raw_write_attribute(:geopoint, '') if geopoint.blank?
#this results in NULL value in INSERT statement
end
---------------------------
#thing_controller.rb
...
def create
@thing = Thing.new
@thing.geopoint = 'GeomFromText("POINT(' + lat + ' ' + lng + ')")'
@thing.save
# This also results in NULL and an error
end
---------------------------
#thing_controller.rb
...
def create
@thing = Thing.new
@thing.geopoint = '1'
@thing.save
# This results in `1` being inserted, but fails because that's invalid spatial data.
end
对我来说,理想的情况是能够强制rails将字符串'GeomFromText(...)'放入它创建的insert语句中,但我不知道该怎么做。
等待全知道社区的想法和意见......
答案 0 :(得分:0)
好的,我最终使用steve klein评论中的第一个链接来插入原始sql。这是我的代码最终的样子:
def create
# Create a Thing instance and assign it the POSTed values
@thing = Thing.new
@thing.assign_attributes(params[:thing], :as => :admin)
# Check to see if all the passed values are valid
if @thing.valid?
# If so, start a DB transaction
ActiveRecord::Base.transaction do
# Insert the minimum data, plus the geopoint
sql = 'INSERT INTO `things`
(`thing_name`,`thing_location`,`geopoint`)
values (
"tmp_insert",
"tmp_location",
GeomFromText("POINT(' + params[:thing][:lat].to_f.to_s + ' ' + params[:thing][:lng].to_f.to_s + ')")
)'
id = ActiveRecord::Base.connection.insert(sql)
# Then load in the newly-created Thing instance and update it's values with the passed values
@real_thing = Thing.find(id)
@real_thing.update_attributes(b, :as => :admin)
end
# Notify the user of success
flash[:message] = { :header => 'Thing successfully created!' }
redirect_to edit_admin_thing_path(@real_thing)
else
# If passed values not valid, alert and re-render form
flash[:error] = { :header => 'Oops! You\'ve got some errors:', :body => @thing.errors.full_messages.join("</p><p>").html_safe }
render 'admin/things/new'
end
end
不漂亮,但有效。